wormhole/ethereum/contracts/GovernanceStructs.sol

183 lines
4.9 KiB
Solidity

// contracts/GovernanceStructs.sol
// SPDX-License-Identifier: Apache 2
pragma solidity ^0.8.0;
import "./libraries/external/BytesLib.sol";
import "./Structs.sol";
/**
* @dev `GovernanceStructs` defines a set of structs and parsing functions
* for minimal struct validation
*/
contract GovernanceStructs {
using BytesLib for bytes;
enum GovernanceAction {
UpgradeContract,
UpgradeGuardianset
}
struct ContractUpgrade {
bytes32 module;
uint8 action;
uint16 chain;
address newContract;
}
struct GuardianSetUpgrade {
bytes32 module;
uint8 action;
uint16 chain;
Structs.GuardianSet newGuardianSet;
uint32 newGuardianSetIndex;
}
struct SetMessageFee {
bytes32 module;
uint8 action;
uint16 chain;
uint256 messageFee;
}
struct TransferFees {
bytes32 module;
uint8 action;
uint16 chain;
uint256 amount;
bytes32 recipient;
}
struct RecoverChainId {
bytes32 module;
uint8 action;
uint256 evmChainId;
uint16 newChainId;
}
/// @dev Parse a contract upgrade (action 1) with minimal validation
function parseContractUpgrade(bytes memory encodedUpgrade) public pure returns (ContractUpgrade memory cu) {
uint index = 0;
cu.module = encodedUpgrade.toBytes32(index);
index += 32;
cu.action = encodedUpgrade.toUint8(index);
index += 1;
require(cu.action == 1, "invalid ContractUpgrade");
cu.chain = encodedUpgrade.toUint16(index);
index += 2;
cu.newContract = address(uint160(uint256(encodedUpgrade.toBytes32(index))));
index += 32;
require(encodedUpgrade.length == index, "invalid ContractUpgrade");
}
/// @dev Parse a guardianSet upgrade (action 2) with minimal validation
function parseGuardianSetUpgrade(bytes memory encodedUpgrade) public pure returns (GuardianSetUpgrade memory gsu) {
uint index = 0;
gsu.module = encodedUpgrade.toBytes32(index);
index += 32;
gsu.action = encodedUpgrade.toUint8(index);
index += 1;
require(gsu.action == 2, "invalid GuardianSetUpgrade");
gsu.chain = encodedUpgrade.toUint16(index);
index += 2;
gsu.newGuardianSetIndex = encodedUpgrade.toUint32(index);
index += 4;
uint8 guardianLength = encodedUpgrade.toUint8(index);
index += 1;
gsu.newGuardianSet = Structs.GuardianSet({
keys : new address[](guardianLength),
expirationTime : 0
});
for(uint i = 0; i < guardianLength; i++) {
gsu.newGuardianSet.keys[i] = encodedUpgrade.toAddress(index);
index += 20;
}
require(encodedUpgrade.length == index, "invalid GuardianSetUpgrade");
}
/// @dev Parse a setMessageFee (action 3) with minimal validation
function parseSetMessageFee(bytes memory encodedSetMessageFee) public pure returns (SetMessageFee memory smf) {
uint index = 0;
smf.module = encodedSetMessageFee.toBytes32(index);
index += 32;
smf.action = encodedSetMessageFee.toUint8(index);
index += 1;
require(smf.action == 3, "invalid SetMessageFee");
smf.chain = encodedSetMessageFee.toUint16(index);
index += 2;
smf.messageFee = encodedSetMessageFee.toUint256(index);
index += 32;
require(encodedSetMessageFee.length == index, "invalid SetMessageFee");
}
/// @dev Parse a transferFees (action 4) with minimal validation
function parseTransferFees(bytes memory encodedTransferFees) public pure returns (TransferFees memory tf) {
uint index = 0;
tf.module = encodedTransferFees.toBytes32(index);
index += 32;
tf.action = encodedTransferFees.toUint8(index);
index += 1;
require(tf.action == 4, "invalid TransferFees");
tf.chain = encodedTransferFees.toUint16(index);
index += 2;
tf.amount = encodedTransferFees.toUint256(index);
index += 32;
tf.recipient = encodedTransferFees.toBytes32(index);
index += 32;
require(encodedTransferFees.length == index, "invalid TransferFees");
}
/// @dev Parse a recoverChainId (action 5) with minimal validation
function parseRecoverChainId(bytes memory encodedRecoverChainId) public pure returns (RecoverChainId memory rci) {
uint index = 0;
rci.module = encodedRecoverChainId.toBytes32(index);
index += 32;
rci.action = encodedRecoverChainId.toUint8(index);
index += 1;
require(rci.action == 5, "invalid RecoverChainId");
rci.evmChainId = encodedRecoverChainId.toUint256(index);
index += 32;
rci.newChainId = encodedRecoverChainId.toUint16(index);
index += 2;
require(encodedRecoverChainId.length == index, "invalid RecoverChainId");
}
}