Source Code
Overview
ETH Balance
0 ETH
More Info
ContractCreator
Multichain Info
N/A
Loading...
Loading
Contract Name:
GroupApprove
Compiler Version
v0.8.18+commit.87f61d96
Optimization Enabled:
Yes with 200 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT
pragma solidity 0.8.18;
import "./IMPC.sol";
import "./ICross.sol";
/**
* @title GroupApprove
* @dev Contract that implements a multi-signature governance mechanism for cross-chain operations
* where proposals require approval from a storeman group before execution
*
* @custom:architecture This contract acts as a governance layer for critical cross-chain operations,
* requiring both foundation proposal and storeman group approval for actions
*/
contract GroupApprove {
/**
* @dev Structure representing an executable task
* @param to Target contract address to call
* @param data Call data to be executed
* @param executed Flag indicating if the task has been executed
*/
struct Task {
address to;
bytes data;
bool executed;
}
/**
* @dev Structure for signature verification data
* @param sigHash Hash of the message being signed
* @param smgID Storeman group ID that signed the message
* @param r R component of the signature (contains X and Y coordinates)
* @param s S component of the signature
*/
struct SigData {
bytes32 sigHash;
bytes32 smgID;
bytes r;
bytes32 s;
}
// slip-0044 chainId
uint256 public chainId;
uint256 public taskCount;
address public foundation;
address public signatureVerifier;
address public oracle;
// proposalId => task
mapping(uint256 => Task) public tasks;
/**
* @dev Enum representing various states a storeman group can be in
*/
enum GroupStatus { none, initial, curveSet, failed, selected, ready, unregistered, dismissed }
/**
* @dev Restricts function access to the foundation address
*/
modifier onlyFoundation() {
require(msg.sender == foundation, "not foundation");
_;
}
/**
* @dev Restricts function access to the contract itself
* Used for functions that should only be called via executing a task
*/
modifier onlySelf() {
require(msg.sender == address(this), "not self");
_;
}
/**
* @dev Validates signature from a storeman group before executing a function
* @param proposalId ID of the proposal being approved
* @param smgID ID of the storeman group signing the approval
* @param r R component of the signature
* @param s S component of the signature
*/
modifier onlySmg(uint proposalId, bytes32 smgID, bytes calldata r, bytes32 s) {
bytes32 sigHash = keccak256(abi.encode(proposalId, chainId));
_verifyMpcSignature(
SigData(
sigHash, smgID, r, s
)
);
_;
}
/**
* @dev Emitted when a new proposal is created
* @param proposalId Unique identifier for the proposal
* @param to Target contract address to call
* @param data Call data to be executed
*/
event Proposal(
uint256 indexed proposalId,
address indexed to,
bytes data
);
/**
* @dev Emitted when a proposal is approved and executed
* @param proposalId Unique identifier for the proposal
* @param to Target contract address that was called
* @param data Call data that was executed
* @param smgID ID of the storeman group that approved the proposal
*/
event ApprovedAndExecuted(
uint256 indexed proposalId,
address indexed to,
bytes data,
bytes32 smgID
);
/**
* @dev Emitted when the foundation address is transferred
* @param oldFoundation Previous foundation address
* @param newFoundation New foundation address
*/
event TransferFoundation(
address indexed oldFoundation,
address indexed newFoundation
);
/**
* @dev Error thrown when signature verification fails
* @param smgID ID of the storeman group
* @param sigHash Hash of the signed message
* @param r R component of the signature
* @param s S component of the signature
*/
error SignatureVerifyFailed(
bytes32 smgID,
bytes32 sigHash,
bytes r,
bytes32 s
);
/**
* @dev Error thrown when a storeman group is not in ready state
* @param smgID ID of the storeman group
* @param status Current status of the storeman group
* @param timestamp Current block timestamp
* @param startTime Start time of the storeman group
* @param endTime End time of the storeman group
*/
error StoremanGroupNotReady(
bytes32 smgID,
uint256 status,
uint256 timestamp,
uint256 startTime,
uint256 endTime
);
/**
* @dev Constructor initializes the contract with key addresses and validates cross-chain configuration
* @param _foundation Address of the foundation that can create proposals
* @param _signatureVerifier Address of the contract used to verify signatures
* @param _oracle Address of the oracle contract that provides storeman group information
* @param _cross Address of the cross-chain bridge contract
*
* @notice Validates that the provided oracle and signatureVerifier match the ones in the cross contract
*/
constructor(address _foundation, address _signatureVerifier, address _oracle, address _cross) {
require(_foundation != address(0), "foundation is empty");
address _oracleCross;
address _signatureVerifierCross;
// cross check oracle and signatureVerifier address with cross contract
(, _oracleCross, , , _signatureVerifierCross) = ICross(_cross).getPartners();
oracle = _oracle;
signatureVerifier = _signatureVerifier;
require(_oracle == _oracleCross, "oracle not match");
require(_signatureVerifier == _signatureVerifierCross, "signatureVerifier not match");
chainId = ICross(_cross).currentChainID(); // read from cross
require(chainId != 0, "chainId is empty");
foundation = _foundation;
}
/**
* @dev Creates a new proposal to be executed after storeman group approval
* @param _chainId Chain ID for which the proposal is intended
* @param _to Target contract address to call
* @param _data Call data to be executed
*
* @notice Only the foundation can create proposals
* @notice The chain ID must match the current chain ID
*/
function proposal(
uint256 _chainId,
address _to,
bytes memory _data
) external onlyFoundation {
require(_data.length > 0, "data is empty");
require(_to != address(0), "to is empty");
require(_chainId == chainId, "chainId not match");
// save task
tasks[taskCount] = Task(_to, _data, false);
emit Proposal(taskCount, _to, _data);
taskCount++;
}
/**
* @dev Approves and executes a proposal with storeman group signature
* @param proposalId ID of the proposal to execute
* @param smgID ID of the storeman group providing approval
* @param r R component of the signature
* @param s S component of the signature
*
* @notice Requires valid signature from an active storeman group
* @notice The task must not have been executed before
*/
function approveAndExecute(
uint256 proposalId,
bytes32 smgID,
bytes calldata r,
bytes32 s
) external onlySmg(proposalId, smgID, r, s) {
Task storage task = tasks[proposalId];
require(task.to != address(0), "task not exists");
require(!task.executed, "task already executed");
(bool success, ) = task.to.call(task.data);
require(success, "call failed");
task.executed = true;
emit ApprovedAndExecuted(proposalId, task.to, task.data, smgID);
}
/**
* @dev Sets the halt status of a cross-chain contract
* @param _to Address of the cross-chain contract to halt or resume
* @param _halt True to halt, false to resume
*
* @notice Only the foundation can call this function
*/
function halt(address _to, bool _halt) external onlyFoundation {
ICross(_to).setHalt(_halt);
}
/**
* @dev Transfers the foundation role to a new address
* @param _newFoundation Address of the new foundation
*
* @notice This function can only be called through executing a task
* @notice Ensures security by requiring both foundation proposal and storeman approval
*/
function transferFoundation(address _newFoundation) external onlySelf {
require(_newFoundation != address(0), "new foundation is empty");
require(_newFoundation != foundation, "new foundation is same as old");
foundation = _newFoundation;
emit TransferFoundation(foundation, _newFoundation);
}
// -------- internal functions --------
/**
* @notice Check if a storeman group is ready and retrieve its cryptographic information
* @param smgID ID of the storeman group to check
* @return curveID ID of the elliptic curve used by the storeman group
* @return PK Public key of the storeman group
*
* @dev Reverts if the storeman group is not in ready state or outside its active time window
*/
function _acquireReadySmgInfo(bytes32 smgID)
internal
view
returns (uint curveID, bytes memory PK)
{
uint8 status;
uint startTime;
uint endTime;
(,status,,,,curveID,,PK,,startTime,endTime) = IMPC(oracle).getStoremanGroupConfig(smgID);
if (!(status == uint8(GroupStatus.ready) && block.timestamp >= startTime && block.timestamp <= endTime)) {
revert StoremanGroupNotReady({
smgID: smgID,
status: uint256(status),
timestamp: block.timestamp,
startTime: startTime,
endTime: endTime
});
}
return (curveID, PK);
}
/**
* @notice Convert bytes to bytes32 at a specific offset
* @param b Bytes array to convert
* @param offset Offset in the bytes array
* @return result The bytes32 value at the specified offset
*
* @dev Uses assembly for gas-efficient conversion
*/
function _bytesToBytes32(bytes memory b, uint offset) internal pure returns (bytes32 result) {
assembly {
result := mload(add(add(b, offset), 32))
}
}
/**
* @dev Verifies an MPC signature for a given message and Storeman Group ID
* @param sig The signature data structure containing all verification components
*
* @dev Reverts with SignatureVerifyFailed if verification fails
* @dev Uses the external signature verifier contract for the actual verification
*/
function _verifyMpcSignature(SigData memory sig) internal {
uint curveID;
bytes memory PK;
// Acquire the curve ID and group public key for the given Storeman Group ID
(curveID, PK) = _acquireReadySmgInfo(sig.smgID);
// Extract the X and Y components of the group public key
bytes32 PKx = _bytesToBytes32(PK, 0);
bytes32 PKy = _bytesToBytes32(PK, 32);
// Extract the X and Y components of the signature
bytes32 Rx = _bytesToBytes32(sig.r, 0);
bytes32 Ry = _bytesToBytes32(sig.r, 32);
// Verify the signature using the Wanchain MPC contract
if (!IMPC(signatureVerifier).verify(curveID, sig.s, PKx, PKy, Rx, Ry, sig.sigHash)) {
revert SignatureVerifyFailed({
smgID: sig.smgID,
sigHash: sig.sigHash,
r: sig.r,
s: sig.s
});
}
}
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.18;
/**
* @title ICross
* @dev Interface for the cross-chain functionality contract that handles asset transfers and communication between chains
*
* @custom:key-features
* - Enable/disable cross-chain functionality
* - Get related contract addresses
* - Get current chain ID information
*/
interface ICross {
/**
* @dev Sets the halt status of the cross-chain contract
*
* @param halt true to halt cross-chain functionality, false to resume
*/
function setHalt(bool halt) external;
/**
* @dev Gets the addresses of related contracts in the cross-chain system
*
* @return tokenManager Token manager contract address
* @return smgAdminProxy Storeman group admin proxy contract address
* @return smgFeeProxy Storeman group fee proxy contract address
* @return quota Quota management contract address
* @return sigVerifier Signature verification contract address
*
* @custom:usage
* - Used to verify key contract addresses
* - Ensures system component consistency
*/
function getPartners() external view returns(address tokenManager, address smgAdminProxy, address smgFeeProxy, address quota, address sigVerifier);
/**
* @dev Gets the ID of the current blockchain
*
* @return uint256 The unique identifier of the current blockchain
*
* @custom:usage
* - Used in cross-chain transactions to verify target chains
* - Ensures messages are sent to the correct target chain
*/
function currentChainID() external view returns (uint256);
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.18;
/**
* @title IMPC
* @dev Interface for Multi-Party Computation (MPC) operations related to storeman groups
*
* @custom:key-features
* - Storeman group configuration retrieval
* - Threshold signature verification
* - Cross-chain security validation
*
* @custom:security
* - Cryptographic signature verification
* - Elliptic curve operations
* - Group public key management
*/
interface IMPC {
/**
* @dev Retrieves the configuration of a Storeman Group by ID
* @param id The ID of the Storeman Group to retrieve
* @return groupId The group ID of the Storeman Group
* @return status The status of the Storeman Group
* @return deposit The deposit amount of the Storeman Group
* @return chain1 The ID of the first chain supported by the Storeman Group
* @return chain2 The ID of the second chain supported by the Storeman Group
* @return curve1 The ID of the first elliptic curve supported by the Storeman Group
* @return curve2 The ID of the second elliptic curve supported by the Storeman Group
* @return gpk1 The Group Public Key for the first elliptic curve
* @return gpk2 The Group Public Key for the second elliptic curve
* @return startTime The start time of the Storeman Group
* @return endTime The end time of the Storeman Group
*
* @custom:usage
* - Used to validate storeman group status
* - Provides cryptographic parameters for signature verification
* - Ensures group is active within its time window
*/
function getStoremanGroupConfig(
bytes32 id
) external view returns (
bytes32 groupId,
uint8 status,
uint deposit,
uint chain1,
uint chain2,
uint curve1,
uint curve2,
bytes memory gpk1,
bytes memory gpk2,
uint startTime,
uint endTime
);
/**
* @dev Verifies a signature using the provided parameters
* @param curveId The ID of the elliptic curve used for the signature
* @param signature The signature to be verified
* @param groupKeyX The X component of the group public key
* @param groupKeyY The Y component of the group public key
* @param randomPointX The X component of the random point
* @param randomPointY The Y component of the random point
* @param message The message that was signed
* @return true if the signature is valid, false otherwise
*
* @custom:security
* - Performs threshold signature verification
* - Uses secure elliptic curve cryptography
* - Critical for cross-chain message authentication
* - Protects against signature forgery attacks
*/
function verify(
uint curveId,
bytes32 signature,
bytes32 groupKeyX,
bytes32 groupKeyY,
bytes32 randomPointX,
bytes32 randomPointY,
bytes32 message
) external returns (bool);
}{
"optimizer": {
"enabled": true,
"runs": 200
},
"evmVersion": "paris",
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
}
}Contract ABI
API[{"inputs":[{"internalType":"address","name":"_foundation","type":"address"},{"internalType":"address","name":"_signatureVerifier","type":"address"},{"internalType":"address","name":"_oracle","type":"address"},{"internalType":"address","name":"_cross","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"bytes32","name":"smgID","type":"bytes32"},{"internalType":"bytes32","name":"sigHash","type":"bytes32"},{"internalType":"bytes","name":"r","type":"bytes"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"SignatureVerifyFailed","type":"error"},{"inputs":[{"internalType":"bytes32","name":"smgID","type":"bytes32"},{"internalType":"uint256","name":"status","type":"uint256"},{"internalType":"uint256","name":"timestamp","type":"uint256"},{"internalType":"uint256","name":"startTime","type":"uint256"},{"internalType":"uint256","name":"endTime","type":"uint256"}],"name":"StoremanGroupNotReady","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"proposalId","type":"uint256"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"bytes","name":"data","type":"bytes"},{"indexed":false,"internalType":"bytes32","name":"smgID","type":"bytes32"}],"name":"ApprovedAndExecuted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"proposalId","type":"uint256"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"bytes","name":"data","type":"bytes"}],"name":"Proposal","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"oldFoundation","type":"address"},{"indexed":true,"internalType":"address","name":"newFoundation","type":"address"}],"name":"TransferFoundation","type":"event"},{"inputs":[{"internalType":"uint256","name":"proposalId","type":"uint256"},{"internalType":"bytes32","name":"smgID","type":"bytes32"},{"internalType":"bytes","name":"r","type":"bytes"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"approveAndExecute","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"chainId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"foundation","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"bool","name":"_halt","type":"bool"}],"name":"halt","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"oracle","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_chainId","type":"uint256"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"proposal","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"signatureVerifier","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"taskCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"tasks","outputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"bool","name":"executed","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_newFoundation","type":"address"}],"name":"transferFoundation","outputs":[],"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
60806040523480156200001157600080fd5b506040516200154a3803806200154a8339810160408190526200003491620002d1565b6001600160a01b038416620000905760405162461bcd60e51b815260206004820152601360248201527f666f756e646174696f6e20697320656d7074790000000000000000000000000060448201526064015b60405180910390fd5b600080826001600160a01b03166373e29b0d6040518163ffffffff1660e01b815260040160a060405180830381865afa158015620000d2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620000f891906200032e565b600480546001600160a01b03199081166001600160a01b038c8116918217909355600380549092168d84161790915594975090955086169092149250620001789150505760405162461bcd60e51b815260206004820152601060248201526f0dee4c2c6d8ca40dcdee840dac2e8c6d60831b604482015260640162000087565b806001600160a01b0316856001600160a01b031614620001db5760405162461bcd60e51b815260206004820152601b60248201527f7369676e61747572655665726966696572206e6f74206d617463680000000000604482015260640162000087565b826001600160a01b031663b179e1e76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200021a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200024091906200039e565b600081815503620002875760405162461bcd60e51b815260206004820152601060248201526f636861696e496420697320656d70747960801b604482015260640162000087565b5050600280546001600160a01b0319166001600160a01b03959095169490941790935550620003b8915050565b80516001600160a01b0381168114620002cc57600080fd5b919050565b60008060008060808587031215620002e857600080fd5b620002f385620002b4565b93506200030360208601620002b4565b92506200031360408601620002b4565b91506200032360608601620002b4565b905092959194509250565b600080600080600060a086880312156200034757600080fd5b6200035286620002b4565b94506200036260208701620002b4565b93506200037260408701620002b4565b92506200038260608701620002b4565b91506200039260808701620002b4565b90509295509295909350565b600060208284031215620003b157600080fd5b5051919050565b61118280620003c86000396000f3fe608060405234801561001057600080fd5b506004361061009e5760003560e01c80638d977672116100665780638d97767214610121578063946951fb146101435780639a8a059214610156578063b6cb58a51461016d578063fde919f61461017657600080fd5b8063229bb7af146100a3578063320432d4146100b8578063413df8aa146100cb57806341fbb050146100de5780637dc0d1d01461010e575b600080fd5b6100b66100b1366004610b23565b610189565b005b6100b66100c6366004610bbd565b61037f565b6100b66100d9366004610bdf565b6104b9565b6002546100f1906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b6004546100f1906001600160a01b031681565b61013461012f366004610c67565b610723565b60405161010593929190610cd0565b6100b6610151366004610d17565b6107db565b61015f60005481565b604051908152602001610105565b61015f60015481565b6003546100f1906001600160a01b031681565b6002546001600160a01b031633146101d95760405162461bcd60e51b815260206004820152600e60248201526d3737ba103337bab73230ba34b7b760911b60448201526064015b60405180910390fd5b600081511161021a5760405162461bcd60e51b815260206004820152600d60248201526c6461746120697320656d70747960981b60448201526064016101d0565b6001600160a01b03821661025e5760405162461bcd60e51b815260206004820152600b60248201526a746f20697320656d70747960a81b60448201526064016101d0565b60005483146102a35760405162461bcd60e51b81526020600482015260116024820152700c6d0c2d2dc92c840dcdee840dac2e8c6d607b1b60448201526064016101d0565b604080516060810182526001600160a01b03848116825260208083018581526000848601819052600180548252600590935294909420835181546001600160a01b0319169316929092178255925191929091908201906103039082610dd3565b50604091820151600291909101805460ff191691151591909117905560015490516001600160a01b03841691907f4c589e53ce12231a0fbfdfff2a62db33943cd4b856b2bd59059f77d42a54c0399061035d908590610e93565b60405180910390a36001805490600061037583610ea6565b9190505550505050565b3330146103b95760405162461bcd60e51b81526020600482015260086024820152673737ba1039b2b63360c11b60448201526064016101d0565b6001600160a01b03811661040f5760405162461bcd60e51b815260206004820152601760248201527f6e657720666f756e646174696f6e20697320656d70747900000000000000000060448201526064016101d0565b6002546001600160a01b039081169082160361046d5760405162461bcd60e51b815260206004820152601d60248201527f6e657720666f756e646174696f6e2069732073616d65206173206f6c6400000060448201526064016101d0565b600280546001600160a01b0319166001600160a01b03831690811790915560405181907fc764c5bb0c90175b0736137bb096f668df98f6927dc0f46ac0326a96b446a49a90600090a350565b84848484846000856000546040516020016104de929190918252602082015260400190565b604051602081830303815290604052805190602001209050610554604051806080016040528083815260200187815260200186868080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250505090825250602001849052610885565b60008b815260056020526040902080546001600160a01b03166105ab5760405162461bcd60e51b815260206004820152600f60248201526e7461736b206e6f742065786973747360881b60448201526064016101d0565b600281015460ff16156105f85760405162461bcd60e51b81526020600482015260156024820152741d185cdac8185b1c9958591e48195e1958dd5d1959605a1b60448201526064016101d0565b80546040516000916001600160a01b031690610618906001850190610ecd565b6000604051808303816000865af19150503d8060008114610655576040519150601f19603f3d011682016040523d82523d6000602084013e61065a565b606091505b50509050806106995760405162461bcd60e51b815260206004820152600b60248201526a18d85b1b0819985a5b195960aa1b60448201526064016101d0565b60018260020160006101000a81548160ff0219169083151502179055508160000160009054906101000a90046001600160a01b03166001600160a01b03168d7ff171265be1c5f8abad69597cc0df677443efea8c2e769e9709e08585f4ef58ac846001018f60405161070c929190610f43565b60405180910390a350505050505050505050505050565b600560205260009081526040902080546001820180546001600160a01b03909216929161074f90610d4e565b80601f016020809104026020016040519081016040528092919081815260200182805461077b90610d4e565b80156107c85780601f1061079d576101008083540402835291602001916107c8565b820191906000526020600020905b8154815290600101906020018083116107ab57829003601f168201915b5050506002909301549192505060ff1683565b6002546001600160a01b031633146108265760405162461bcd60e51b815260206004820152600e60248201526d3737ba103337bab73230ba34b7b760911b60448201526064016101d0565b60405163f495438760e01b815281151560048201526001600160a01b0383169063f495438790602401600060405180830381600087803b15801561086957600080fd5b505af115801561087d573d6000803e3d6000fd5b505050505050565b600060606108968360200151610994565b60208181015160408084015188820151808501519083015160035460608c01518c518651631161eded60e21b8152600481018c9052602481019290925260448201889052606482018690526084820185905260a4820184905260c48201529451989a509698509396919590946001600160a01b0390911692634587b7b49260e4808301939282900301816000875af1158015610936573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061095a9190610fd7565b61098b57602087015187516040808a015160608b01519151635d2d123b60e11b81526101d094939290600401610ff4565b50505050505050565b600480546040516344cefb6960e01b81526000926060928492839283926001600160a01b0316916344cefb69916109d1918a910190815260200190565b600060405180830381865afa1580156109ee573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610a169190810190611082565b949e50919c50969a50985090965060059550610a33945050505050565b60ff168360ff16148015610a475750814210155b8015610a535750804211155b610a90576040516320b0fccf60e01b81526004810187905260ff84166024820152426044820152606481018390526084810182905260a4016101d0565b505050915091565b80356001600160a01b0381168114610aaf57600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715610af357610af3610ab4565b604052919050565b600067ffffffffffffffff821115610b1557610b15610ab4565b50601f01601f191660200190565b600080600060608486031215610b3857600080fd5b83359250610b4860208501610a98565b9150604084013567ffffffffffffffff811115610b6457600080fd5b8401601f81018613610b7557600080fd5b8035610b88610b8382610afb565b610aca565b818152876020838501011115610b9d57600080fd5b816020840160208301376000602083830101528093505050509250925092565b600060208284031215610bcf57600080fd5b610bd882610a98565b9392505050565b600080600080600060808688031215610bf757600080fd5b8535945060208601359350604086013567ffffffffffffffff80821115610c1d57600080fd5b818801915088601f830112610c3157600080fd5b813581811115610c4057600080fd5b896020828501011115610c5257600080fd5b96999598505060200195606001359392505050565b600060208284031215610c7957600080fd5b5035919050565b60005b83811015610c9b578181015183820152602001610c83565b50506000910152565b60008151808452610cbc816020860160208601610c80565b601f01601f19169290920160200192915050565b6001600160a01b0384168152606060208201819052600090610cf490830185610ca4565b90508215156040830152949350505050565b8015158114610d1457600080fd5b50565b60008060408385031215610d2a57600080fd5b610d3383610a98565b91506020830135610d4381610d06565b809150509250929050565b600181811c90821680610d6257607f821691505b602082108103610d8257634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115610dce57600081815260208120601f850160051c81016020861015610daf5750805b601f850160051c820191505b8181101561087d57828155600101610dbb565b505050565b815167ffffffffffffffff811115610ded57610ded610ab4565b610e0181610dfb8454610d4e565b84610d88565b602080601f831160018114610e365760008415610e1e5750858301515b600019600386901b1c1916600185901b17855561087d565b600085815260208120601f198616915b82811015610e6557888601518255948401946001909101908401610e46565b5085821015610e835787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b602081526000610bd86020830184610ca4565b600060018201610ec657634e487b7160e01b600052601160045260246000fd5b5060010190565b6000808354610edb81610d4e565b60018281168015610ef35760018114610f0857610f37565b60ff1984168752821515830287019450610f37565b8760005260208060002060005b85811015610f2e5781548a820152908401908201610f15565b50505082870194505b50929695505050505050565b604081526000808454610f5581610d4e565b8060408601526060600180841660008114610f775760018114610f9157610fc2565b60ff1985168884015283151560051b880183019550610fc2565b8960005260208060002060005b86811015610fb95781548b8201870152908401908201610f9e565b8a018501975050505b50505050506020929092019290925292915050565b600060208284031215610fe957600080fd5b8151610bd881610d06565b8481528360208201526080604082015260006110136080830185610ca4565b905082606083015295945050505050565b805160ff81168114610aaf57600080fd5b600082601f83011261104657600080fd5b8151611054610b8382610afb565b81815284602083860101111561106957600080fd5b61107a826020830160208701610c80565b949350505050565b60008060008060008060008060008060006101608c8e0312156110a457600080fd5b8b519a506110b460208d01611024565b995060408c0151985060608c0151975060808c0151965060a08c0151955060c08c0151945060e08c015167ffffffffffffffff8111156110f357600080fd5b6110ff8e828f01611035565b9450506101008c015167ffffffffffffffff81111561111d57600080fd5b6111298e828f01611035565b9350506101208c015191506101408c015190509295989b509295989b909396995056fea2646970667358221220ba41d8358b895758c0f4f0b64e5b62fa1c14b479162cd23cc56bc3c6a1cade8164736f6c63430008120033000000000000000000000000f6eb3cb4b187d3201afbf96a38e62367325b29f90000000000000000000000005292b2936dad44edfbfb2929f9f246304167843b0000000000000000000000003274f4a76b0d55c99a852d18565ebdfb67ab313a00000000000000000000000008bad1a48b0b08bf769f83ba30c1dad0f8bb8b6b
Deployed Bytecode
0x608060405234801561001057600080fd5b506004361061009e5760003560e01c80638d977672116100665780638d97767214610121578063946951fb146101435780639a8a059214610156578063b6cb58a51461016d578063fde919f61461017657600080fd5b8063229bb7af146100a3578063320432d4146100b8578063413df8aa146100cb57806341fbb050146100de5780637dc0d1d01461010e575b600080fd5b6100b66100b1366004610b23565b610189565b005b6100b66100c6366004610bbd565b61037f565b6100b66100d9366004610bdf565b6104b9565b6002546100f1906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b6004546100f1906001600160a01b031681565b61013461012f366004610c67565b610723565b60405161010593929190610cd0565b6100b6610151366004610d17565b6107db565b61015f60005481565b604051908152602001610105565b61015f60015481565b6003546100f1906001600160a01b031681565b6002546001600160a01b031633146101d95760405162461bcd60e51b815260206004820152600e60248201526d3737ba103337bab73230ba34b7b760911b60448201526064015b60405180910390fd5b600081511161021a5760405162461bcd60e51b815260206004820152600d60248201526c6461746120697320656d70747960981b60448201526064016101d0565b6001600160a01b03821661025e5760405162461bcd60e51b815260206004820152600b60248201526a746f20697320656d70747960a81b60448201526064016101d0565b60005483146102a35760405162461bcd60e51b81526020600482015260116024820152700c6d0c2d2dc92c840dcdee840dac2e8c6d607b1b60448201526064016101d0565b604080516060810182526001600160a01b03848116825260208083018581526000848601819052600180548252600590935294909420835181546001600160a01b0319169316929092178255925191929091908201906103039082610dd3565b50604091820151600291909101805460ff191691151591909117905560015490516001600160a01b03841691907f4c589e53ce12231a0fbfdfff2a62db33943cd4b856b2bd59059f77d42a54c0399061035d908590610e93565b60405180910390a36001805490600061037583610ea6565b9190505550505050565b3330146103b95760405162461bcd60e51b81526020600482015260086024820152673737ba1039b2b63360c11b60448201526064016101d0565b6001600160a01b03811661040f5760405162461bcd60e51b815260206004820152601760248201527f6e657720666f756e646174696f6e20697320656d70747900000000000000000060448201526064016101d0565b6002546001600160a01b039081169082160361046d5760405162461bcd60e51b815260206004820152601d60248201527f6e657720666f756e646174696f6e2069732073616d65206173206f6c6400000060448201526064016101d0565b600280546001600160a01b0319166001600160a01b03831690811790915560405181907fc764c5bb0c90175b0736137bb096f668df98f6927dc0f46ac0326a96b446a49a90600090a350565b84848484846000856000546040516020016104de929190918252602082015260400190565b604051602081830303815290604052805190602001209050610554604051806080016040528083815260200187815260200186868080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250505090825250602001849052610885565b60008b815260056020526040902080546001600160a01b03166105ab5760405162461bcd60e51b815260206004820152600f60248201526e7461736b206e6f742065786973747360881b60448201526064016101d0565b600281015460ff16156105f85760405162461bcd60e51b81526020600482015260156024820152741d185cdac8185b1c9958591e48195e1958dd5d1959605a1b60448201526064016101d0565b80546040516000916001600160a01b031690610618906001850190610ecd565b6000604051808303816000865af19150503d8060008114610655576040519150601f19603f3d011682016040523d82523d6000602084013e61065a565b606091505b50509050806106995760405162461bcd60e51b815260206004820152600b60248201526a18d85b1b0819985a5b195960aa1b60448201526064016101d0565b60018260020160006101000a81548160ff0219169083151502179055508160000160009054906101000a90046001600160a01b03166001600160a01b03168d7ff171265be1c5f8abad69597cc0df677443efea8c2e769e9709e08585f4ef58ac846001018f60405161070c929190610f43565b60405180910390a350505050505050505050505050565b600560205260009081526040902080546001820180546001600160a01b03909216929161074f90610d4e565b80601f016020809104026020016040519081016040528092919081815260200182805461077b90610d4e565b80156107c85780601f1061079d576101008083540402835291602001916107c8565b820191906000526020600020905b8154815290600101906020018083116107ab57829003601f168201915b5050506002909301549192505060ff1683565b6002546001600160a01b031633146108265760405162461bcd60e51b815260206004820152600e60248201526d3737ba103337bab73230ba34b7b760911b60448201526064016101d0565b60405163f495438760e01b815281151560048201526001600160a01b0383169063f495438790602401600060405180830381600087803b15801561086957600080fd5b505af115801561087d573d6000803e3d6000fd5b505050505050565b600060606108968360200151610994565b60208181015160408084015188820151808501519083015160035460608c01518c518651631161eded60e21b8152600481018c9052602481019290925260448201889052606482018690526084820185905260a4820184905260c48201529451989a509698509396919590946001600160a01b0390911692634587b7b49260e4808301939282900301816000875af1158015610936573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061095a9190610fd7565b61098b57602087015187516040808a015160608b01519151635d2d123b60e11b81526101d094939290600401610ff4565b50505050505050565b600480546040516344cefb6960e01b81526000926060928492839283926001600160a01b0316916344cefb69916109d1918a910190815260200190565b600060405180830381865afa1580156109ee573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610a169190810190611082565b949e50919c50969a50985090965060059550610a33945050505050565b60ff168360ff16148015610a475750814210155b8015610a535750804211155b610a90576040516320b0fccf60e01b81526004810187905260ff84166024820152426044820152606481018390526084810182905260a4016101d0565b505050915091565b80356001600160a01b0381168114610aaf57600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715610af357610af3610ab4565b604052919050565b600067ffffffffffffffff821115610b1557610b15610ab4565b50601f01601f191660200190565b600080600060608486031215610b3857600080fd5b83359250610b4860208501610a98565b9150604084013567ffffffffffffffff811115610b6457600080fd5b8401601f81018613610b7557600080fd5b8035610b88610b8382610afb565b610aca565b818152876020838501011115610b9d57600080fd5b816020840160208301376000602083830101528093505050509250925092565b600060208284031215610bcf57600080fd5b610bd882610a98565b9392505050565b600080600080600060808688031215610bf757600080fd5b8535945060208601359350604086013567ffffffffffffffff80821115610c1d57600080fd5b818801915088601f830112610c3157600080fd5b813581811115610c4057600080fd5b896020828501011115610c5257600080fd5b96999598505060200195606001359392505050565b600060208284031215610c7957600080fd5b5035919050565b60005b83811015610c9b578181015183820152602001610c83565b50506000910152565b60008151808452610cbc816020860160208601610c80565b601f01601f19169290920160200192915050565b6001600160a01b0384168152606060208201819052600090610cf490830185610ca4565b90508215156040830152949350505050565b8015158114610d1457600080fd5b50565b60008060408385031215610d2a57600080fd5b610d3383610a98565b91506020830135610d4381610d06565b809150509250929050565b600181811c90821680610d6257607f821691505b602082108103610d8257634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115610dce57600081815260208120601f850160051c81016020861015610daf5750805b601f850160051c820191505b8181101561087d57828155600101610dbb565b505050565b815167ffffffffffffffff811115610ded57610ded610ab4565b610e0181610dfb8454610d4e565b84610d88565b602080601f831160018114610e365760008415610e1e5750858301515b600019600386901b1c1916600185901b17855561087d565b600085815260208120601f198616915b82811015610e6557888601518255948401946001909101908401610e46565b5085821015610e835787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b602081526000610bd86020830184610ca4565b600060018201610ec657634e487b7160e01b600052601160045260246000fd5b5060010190565b6000808354610edb81610d4e565b60018281168015610ef35760018114610f0857610f37565b60ff1984168752821515830287019450610f37565b8760005260208060002060005b85811015610f2e5781548a820152908401908201610f15565b50505082870194505b50929695505050505050565b604081526000808454610f5581610d4e565b8060408601526060600180841660008114610f775760018114610f9157610fc2565b60ff1985168884015283151560051b880183019550610fc2565b8960005260208060002060005b86811015610fb95781548b8201870152908401908201610f9e565b8a018501975050505b50505050506020929092019290925292915050565b600060208284031215610fe957600080fd5b8151610bd881610d06565b8481528360208201526080604082015260006110136080830185610ca4565b905082606083015295945050505050565b805160ff81168114610aaf57600080fd5b600082601f83011261104657600080fd5b8151611054610b8382610afb565b81815284602083860101111561106957600080fd5b61107a826020830160208701610c80565b949350505050565b60008060008060008060008060008060006101608c8e0312156110a457600080fd5b8b519a506110b460208d01611024565b995060408c0151985060608c0151975060808c0151965060a08c0151955060c08c0151945060e08c015167ffffffffffffffff8111156110f357600080fd5b6110ff8e828f01611035565b9450506101008c015167ffffffffffffffff81111561111d57600080fd5b6111298e828f01611035565b9350506101208c015191506101408c015190509295989b509295989b909396995056fea2646970667358221220ba41d8358b895758c0f4f0b64e5b62fa1c14b479162cd23cc56bc3c6a1cade8164736f6c63430008120033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000f6eb3cb4b187d3201afbf96a38e62367325b29f90000000000000000000000005292b2936dad44edfbfb2929f9f246304167843b0000000000000000000000003274f4a76b0d55c99a852d18565ebdfb67ab313a00000000000000000000000008bad1a48b0b08bf769f83ba30c1dad0f8bb8b6b
-----Decoded View---------------
Arg [0] : _foundation (address): 0xF6eB3CB4b187d3201AfBF96A38e62367325b29F9
Arg [1] : _signatureVerifier (address): 0x5292B2936daD44EdFbFB2929f9f246304167843b
Arg [2] : _oracle (address): 0x3274F4a76B0D55c99a852d18565EBDfb67aB313A
Arg [3] : _cross (address): 0x08bad1A48b0B08Bf769f83ba30c1DaD0F8Bb8b6B
-----Encoded View---------------
4 Constructor Arguments found :
Arg [0] : 000000000000000000000000f6eb3cb4b187d3201afbf96a38e62367325b29f9
Arg [1] : 0000000000000000000000005292b2936dad44edfbfb2929f9f246304167843b
Arg [2] : 0000000000000000000000003274f4a76b0d55c99a852d18565ebdfb67ab313a
Arg [3] : 00000000000000000000000008bad1a48b0b08bf769f83ba30c1dad0f8bb8b6b
Loading...
Loading
Loading...
Loading
Loading...
Loading
Loading...
Loading
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.