Overview
S Balance
S Value
$0.00More Info
Private Name Tags
ContractCreator
Loading...
Loading
Contract Name:
PayloadsController
Compiler Version
v0.8.22+commit.4fc1097e
Optimization Enabled:
Yes with 200 runs
Other Settings:
shanghai EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.8; import {PayloadsControllerCore, PayloadsControllerUtils} from './PayloadsControllerCore.sol'; import {IPayloadsController, IBaseReceiverPortal} from './interfaces/IPayloadsController.sol'; import {Errors} from '../libraries/Errors.sol'; /** * @title PayloadsController * @author BGD Labs * @notice Contract with the logic to manage receiving cross chain messages. This contract knows how to receive and decode messages from CrossChainController */ contract PayloadsController is PayloadsControllerCore, IPayloadsController { /// @inheritdoc IPayloadsController address public immutable MESSAGE_ORIGINATOR; /// @inheritdoc IPayloadsController address public immutable CROSS_CHAIN_CONTROLLER; /// @inheritdoc IPayloadsController uint256 public immutable ORIGIN_CHAIN_ID; /** * @param crossChainController address of the CrossChainController contract deployed on current chain. This contract is the one responsible to send here the voting configurations once they are bridged. * @param messageOriginator address of the contract where the message originates (mainnet governance) * @param originChainId the id of the network where the messages originate from */ constructor( address crossChainController, address messageOriginator, uint256 originChainId ) { require( crossChainController != address(0), Errors.INVALID_CROSS_CHAIN_CONTROLLER_ADDRESS ); require( messageOriginator != address(0), Errors.INVALID_MESSAGE_ORIGINATOR_ADDRESS ); require(originChainId > 0, Errors.INVALID_ORIGIN_CHAIN_ID); CROSS_CHAIN_CONTROLLER = crossChainController; MESSAGE_ORIGINATOR = messageOriginator; ORIGIN_CHAIN_ID = originChainId; } /// @inheritdoc IBaseReceiverPortal function receiveCrossChainMessage( address originSender, uint256 originChainId, bytes memory message ) external { require( msg.sender == CROSS_CHAIN_CONTROLLER && originSender == MESSAGE_ORIGINATOR && originChainId == ORIGIN_CHAIN_ID, Errors.WRONG_MESSAGE_ORIGIN ); try this.decodeMessage(message) returns ( uint40 payloadId, PayloadsControllerUtils.AccessControl accessLevel, uint40 proposalVoteActivationTimestamp ) { _queuePayload(payloadId, accessLevel, proposalVoteActivationTimestamp); bytes memory empty; emit PayloadExecutionMessageReceived( originSender, originChainId, true, message, empty ); } catch (bytes memory decodingError) { emit PayloadExecutionMessageReceived( originSender, originChainId, false, message, decodingError ); } } /// @inheritdoc IPayloadsController function decodeMessage( bytes memory message ) external pure returns (uint40, PayloadsControllerUtils.AccessControl, uint40) { return abi.decode( message, (uint40, PayloadsControllerUtils.AccessControl, uint40) ); } }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.8; import {OwnableWithGuardian} from 'aave-delivery-infrastructure/contracts/old-oz/OwnableWithGuardian.sol'; import {Rescuable, RescuableBase} from 'solidity-utils/contracts/utils/Rescuable.sol'; import {IRescuable, IRescuableBase} from 'solidity-utils/contracts/utils/interfaces/IRescuable.sol'; import {IERC20} from 'openzeppelin-contracts/contracts/token/ERC20/IERC20.sol'; import {Initializable} from 'aave-delivery-infrastructure/contracts/old-oz/Initializable.sol'; import {SafeERC20} from 'openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol'; import {SafeCast} from 'openzeppelin-contracts/contracts/utils/math/SafeCast.sol'; import {IPayloadsControllerCore, PayloadsControllerUtils} from './interfaces/IPayloadsControllerCore.sol'; import {IExecutor} from './interfaces/IExecutor.sol'; import {Errors} from '../libraries/Errors.sol'; /** * @title PayloadsControllerCore * @author BGD Labs * @notice this contract contains the logic to create and execute a payload. * @dev To execute a created payload, the payload id must be bridged from governance chain. * @dev The methods to update the contract configuration are callable only by owner. Owner being the registered lvl1 Executor. So to update the PayloadsController configuration, a proposal will need to pass in gov chain and be executed by the appropriate executor. */ abstract contract PayloadsControllerCore is OwnableWithGuardian, Rescuable, IPayloadsControllerCore, Initializable { using SafeCast for uint256; using SafeERC20 for IERC20; uint40 internal _payloadsCount; // stores the executor configuration for every lvl of access control mapping(PayloadsControllerUtils.AccessControl => ExecutorConfig) internal _accessLevelToExecutorConfig; mapping(uint40 => Payload) internal _payloads; // should be always set with respect to the proposal flow duration // for example: voting takes 5 days + 2 days for bridging + 3 days for cooldown + 2 days of safety gap // then expirationDelay should be not less then 12 days. // As expiration delay of proposal is 30 days, payload needs to be able to live longer as its created before and // will be executed after. // so nobody should be able to set expiration delay less then that /// @inheritdoc IPayloadsControllerCore function EXPIRATION_DELAY() public pure virtual returns (uint40) { return 35 days; } /// @inheritdoc IPayloadsControllerCore function GRACE_PERIOD() public pure virtual returns (uint40) { return 7 days; } /// @inheritdoc IPayloadsControllerCore function MIN_EXECUTION_DELAY() public view virtual returns (uint40) { return 1 days; } /// @inheritdoc IPayloadsControllerCore function MAX_EXECUTION_DELAY() public view virtual returns (uint40) { return 10 days; } function initialize( address owner, address guardian, UpdateExecutorInput[] calldata executors ) public virtual initializer { require(executors.length != 0, Errors.SHOULD_BE_AT_LEAST_ONE_EXECUTOR); _updateExecutors(executors); _updateGuardian(guardian); _transferOwnership(owner); } /// @inheritdoc IPayloadsControllerCore function createPayload( ExecutionAction[] calldata actions ) public virtual returns (uint40) { require(actions.length != 0, Errors.INVALID_EMPTY_TARGETS); uint40 payloadId = _payloadsCount++; uint40 creationTime = uint40(block.timestamp); Payload storage newPayload = _payloads[payloadId]; newPayload.creator = msg.sender; newPayload.state = PayloadState.Created; newPayload.createdAt = creationTime; newPayload.expirationTime = creationTime + EXPIRATION_DELAY(); newPayload.gracePeriod = GRACE_PERIOD(); PayloadsControllerUtils.AccessControl maximumAccessLevelRequired; for (uint256 i = 0; i < actions.length; i++) { require(actions[i].target != address(0), Errors.INVALID_ACTION_TARGET); require( actions[i].accessLevel > PayloadsControllerUtils.AccessControl.Level_null, Errors.INVALID_ACTION_ACCESS_LEVEL ); require( _accessLevelToExecutorConfig[actions[i].accessLevel].executor != address(0), Errors.EXECUTOR_WAS_NOT_SPECIFIED_FOR_REQUESTED_ACCESS_LEVEL ); newPayload.actions.push(actions[i]); if (actions[i].accessLevel > maximumAccessLevelRequired) { maximumAccessLevelRequired = actions[i].accessLevel; } } newPayload.maximumAccessLevelRequired = maximumAccessLevelRequired; ExecutorConfig memory maxRequiredExecutorConfig = _accessLevelToExecutorConfig[ maximumAccessLevelRequired ]; newPayload.delay = maxRequiredExecutorConfig.delay; emit PayloadCreated( payloadId, msg.sender, actions, maximumAccessLevelRequired ); return payloadId; } /// @inheritdoc IPayloadsControllerCore function executePayload(uint40 payloadId) external payable { Payload storage payload = _payloads[payloadId]; require( _getPayloadState(payload) == PayloadState.Queued, Errors.PAYLOAD_NOT_IN_QUEUED_STATE ); uint256 executionTime = payload.queuedAt + payload.delay; require(block.timestamp > executionTime, Errors.TIMELOCK_NOT_FINISHED); payload.state = PayloadState.Executed; payload.executedAt = uint40(block.timestamp); for (uint256 i = 0; i < payload.actions.length; i++) { ExecutionAction storage action = payload.actions[i]; IExecutor executor = IExecutor( _accessLevelToExecutorConfig[action.accessLevel].executor ); executor.executeTransaction{value: action.value}( action.target, action.value, action.signature, action.callData, action.withDelegateCall ); } emit PayloadExecuted(payloadId); } /// @inheritdoc IPayloadsControllerCore function cancelPayload( uint40 payloadId ) external virtual onlyGuardian { _cancelPayload(payloadId); } /// @inheritdoc IPayloadsControllerCore function updateExecutors( UpdateExecutorInput[] calldata executors ) external virtual onlyOwner { _updateExecutors(executors); } /// @inheritdoc IPayloadsControllerCore function getPayloadById( uint40 payloadId ) external view returns (Payload memory) { Payload memory payload = _payloads[payloadId]; payload.state = _getPayloadState(payload); return payload; } /// @inheritdoc IPayloadsControllerCore function getPayloadState( uint40 payloadId ) external view returns (PayloadState) { return _getPayloadState(_payloads[payloadId]); } /// @inheritdoc IPayloadsControllerCore function getPayloadsCount() external view returns (uint40) { return _payloadsCount; } /// @inheritdoc IPayloadsControllerCore function getExecutorSettingsByAccessControl( PayloadsControllerUtils.AccessControl accessControl ) external view returns (ExecutorConfig memory) { return _accessLevelToExecutorConfig[accessControl]; } /// @inheritdoc Rescuable function whoCanRescue() public view override(Rescuable) returns (address) { return owner(); } /// @inheritdoc IRescuableBase function maxRescue( address erc20Token ) public view override(IRescuableBase, RescuableBase) returns (uint256) { return IERC20(erc20Token).balanceOf(address(this)); } receive() external payable {} /** * @notice method to cancel a payload * @param payloadId id of the payload that needs to be canceled */ function _cancelPayload(uint40 payloadId) internal { Payload storage payload = _payloads[payloadId]; PayloadState payloadState = _getPayloadState(payload); require( payloadState < PayloadState.Executed && payloadState >= PayloadState.Created, Errors.PAYLOAD_NOT_IN_THE_CORRECT_STATE ); payload.state = PayloadState.Cancelled; payload.cancelledAt = uint40(block.timestamp); emit PayloadCancelled(payloadId); } /** * @notice method to get the current state of a payload * @param payload object with all pertinent payload information * @return current state of the payload */ function _getPayloadState( Payload memory payload ) internal view returns (PayloadState) { PayloadState state = payload.state; if (state == PayloadState.None || state >= PayloadState.Executed) { return state; } if ( (state == PayloadState.Created && block.timestamp >= payload.expirationTime) || (state == PayloadState.Queued && block.timestamp >= payload.queuedAt + payload.delay + payload.gracePeriod) ) { return PayloadState.Expired; } return state; } /** * @notice method to queue a payload * @param payloadId id of the payload that needs to be queued * @param accessLevel access level used for the proposal voting * @param proposalVoteActivationTimestamp proposal vote activation timestamp in seconds * @dev this method will be called when a payload is bridged from governance chain */ function _queuePayload( uint40 payloadId, PayloadsControllerUtils.AccessControl accessLevel, uint40 proposalVoteActivationTimestamp ) internal { Payload storage payload = _payloads[payloadId]; require( _getPayloadState(payload) == PayloadState.Created, Errors.PAYLOAD_NOT_IN_CREATED_STATE ); // by allowing >= it enables the proposal to use a higher level of voting configuration // than the one set by the payload actions require( accessLevel >= payload.maximumAccessLevelRequired, Errors.INVALID_PROPOSAL_ACCESS_LEVEL ); // this checks that the payload has been created before the proposal vote started. // this ensures that the voters where able to check the content of the payload they voted on require( proposalVoteActivationTimestamp > payload.createdAt, Errors.PAYLOAD_NOT_CREATED_BEFORE_PROPOSAL ); payload.state = PayloadState.Queued; payload.queuedAt = uint40(block.timestamp); emit PayloadQueued(payloadId); } /** * @notice add new executor configs * @param executors array of UpdateExecutorInput with needed executor configurations */ function _updateExecutors(UpdateExecutorInput[] memory executors) internal { for (uint256 i = 0; i < executors.length; i++) { UpdateExecutorInput memory newExecutorConfig = executors[i]; require( newExecutorConfig.executorConfig.executor != address(0), Errors.INVALID_EXECUTOR_ADDRESS ); require( newExecutorConfig.accessLevel > PayloadsControllerUtils.AccessControl.Level_null, Errors.INVALID_EXECUTOR_ACCESS_LEVEL ); require( newExecutorConfig.executorConfig.delay >= MIN_EXECUTION_DELAY() && newExecutorConfig.executorConfig.delay <= MAX_EXECUTION_DELAY(), Errors.INVALID_EXECUTOR_DELAY ); // check that the new executor is not already being used in a different level PayloadsControllerUtils.AccessControl levelToCheck = newExecutorConfig .accessLevel == PayloadsControllerUtils.AccessControl.Level_1 ? PayloadsControllerUtils.AccessControl.Level_2 : PayloadsControllerUtils.AccessControl.Level_1; require( _accessLevelToExecutorConfig[levelToCheck].executor != newExecutorConfig.executorConfig.executor, Errors.EXECUTOR_ALREADY_SET_IN_DIFFERENT_LEVEL ); _accessLevelToExecutorConfig[ newExecutorConfig.accessLevel ] = newExecutorConfig.executorConfig; emit ExecutorSet( newExecutorConfig.accessLevel, newExecutorConfig.executorConfig.executor, newExecutorConfig.executorConfig.delay ); } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import {IBaseReceiverPortal} from 'aave-delivery-infrastructure/contracts/interfaces/IBaseReceiverPortal.sol'; import {IPayloadsControllerCore} from './IPayloadsControllerCore.sol'; import {PayloadsControllerUtils} from '../PayloadsControllerUtils.sol'; /** * @title IPayloadsController * @author BGD Labs * @notice interface containing the objects, events and methods definitions of the PayloadsController contract */ interface IPayloadsController is IBaseReceiverPortal, IPayloadsControllerCore { /** * @notice get contract address from where the messages come * @return address of the message registry */ function CROSS_CHAIN_CONTROLLER() external view returns (address); /** * @notice get chain id of the message originator network * @return chain id of the originator network */ function ORIGIN_CHAIN_ID() external view returns (uint256); /** * @notice get address of the message sender in originator network * @return address of the originator contract */ function MESSAGE_ORIGINATOR() external view returns (address); /** * @notice method to decode a message from from governance chain * @param message encoded message with message type * @return payloadId, accessLevel, proposalVoteActivationTimestamp from the decoded message */ function decodeMessage( bytes memory message ) external pure returns (uint40, PayloadsControllerUtils.AccessControl, uint40); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @title Errors library * @author BGD Labs * @notice Defines the error messages emitted by the different contracts of the Aave Governance V3 */ library Errors { string public constant VOTING_PORTALS_COUNT_NOT_0 = '1'; // to be able to rescue voting portals count must be 0 string public constant AT_LEAST_ONE_PAYLOAD = '2'; // to create a proposal, it must have at least one payload string public constant VOTING_PORTAL_NOT_APPROVED = '3'; // the voting portal used to vote on proposal must be approved string public constant PROPOSITION_POWER_IS_TOO_LOW = '4'; // proposition power of proposal creator must be equal or higher than the specified threshold for the access level string public constant PROPOSAL_NOT_IN_CREATED_STATE = '5'; // proposal should be in the CREATED state string public constant PROPOSAL_NOT_IN_ACTIVE_STATE = '6'; // proposal must be in an ACTIVE state string public constant PROPOSAL_NOT_IN_QUEUED_STATE = '7'; // proposal must be in a QUEUED state string public constant VOTING_START_COOLDOWN_PERIOD_NOT_PASSED = '8'; // to activate a proposal vote, the cool down delay must pass string public constant CALLER_NOT_A_VALID_VOTING_PORTAL = '9'; // only an allowed voting portal can queue a proposal string public constant QUEUE_COOLDOWN_PERIOD_NOT_PASSED = '10'; // to execute a proposal a cooldown delay must pass string public constant PROPOSAL_NOT_IN_THE_CORRECT_STATE = '11'; // proposal must be created but not executed yet to be able to be canceled string public constant CALLER_NOT_GOVERNANCE = '12'; // caller must be governance string public constant VOTER_ALREADY_VOTED_ON_PROPOSAL = '13'; // voter can only vote once per proposal using voting portal string public constant WRONG_MESSAGE_ORIGIN = '14'; // received message must come from registered source address, chain id, CrossChainController string public constant NO_VOTING_ASSETS = '15'; // Strategy must have voting assets string public constant PROPOSAL_VOTE_ALREADY_CREATED = '16'; // vote on proposal can only be created once string public constant INVALID_SIGNATURE = '17'; // submitted signature is not valid string public constant PROPOSAL_VOTE_NOT_FINISHED = '18'; // proposal vote must be finished string public constant PROPOSAL_VOTE_NOT_IN_ACTIVE_STATE = '19'; // proposal vote must be in active state string public constant PROPOSAL_VOTE_ALREADY_EXISTS = '20'; // proposal vote already exists string public constant VOTE_ONCE_FOR_ASSET = '21'; // an asset can only be used once per vote string public constant USER_BALANCE_DOES_NOT_EXISTS = '22'; // to vote an user must have balance in the token the user is voting with string public constant USER_VOTING_BALANCE_IS_ZERO = '23'; // to vote an user must have some balance between all the tokens selected for voting string public constant MISSING_AAVE_ROOTS = '24'; // must have AAVE roots registered to use strategy string public constant MISSING_STK_AAVE_ROOTS = '25'; // must have stkAAVE roots registered to use strategy string public constant MISSING_STK_AAVE_SLASHING_EXCHANGE_RATE = '26'; // must have stkAAVE slashing exchange rate registered to use strategy string public constant UNPROCESSED_STORAGE_ROOT = '27'; // root must be registered beforehand string public constant NOT_ENOUGH_MSG_VALUE = '28'; // method was not called with enough value to execute the call string public constant FAILED_ACTION_EXECUTION = '29'; // action failed to execute string public constant SHOULD_BE_AT_LEAST_ONE_EXECUTOR = '30'; // at least one executor is needed string public constant INVALID_EMPTY_TARGETS = '31'; // target of the payload execution must not be empty string public constant EXECUTOR_WAS_NOT_SPECIFIED_FOR_REQUESTED_ACCESS_LEVEL = '32'; // payload executor must be registered for the specified payload access level string public constant PAYLOAD_NOT_IN_QUEUED_STATE = '33'; // payload must be en the queued state string public constant TIMELOCK_NOT_FINISHED = '34'; // delay has not passed before execution can be called string public constant PAYLOAD_NOT_IN_THE_CORRECT_STATE = '35'; // payload must be created but not executed yet to be able to be canceled string public constant PAYLOAD_NOT_IN_CREATED_STATE = '36'; // payload must be in the created state string public constant MISSING_A_AAVE_ROOTS = '37'; // must have aAAVE roots registered to use strategy string public constant MISSING_PROPOSAL_BLOCK_HASH = '38'; // block hash for this proposal was not bridged before string public constant PROPOSAL_VOTE_CONFIGURATION_ALREADY_BRIDGED = '39'; // configuration for this proposal bridged already string public constant INVALID_VOTING_PORTAL_ADDRESS = '40'; // voting portal address can't be 0x0 string public constant INVALID_POWER_STRATEGY = '41'; // 0x0 is not valid as the power strategy string public constant INVALID_EXECUTOR_ADDRESS = '42'; // executor address can't be 0x0 string public constant EXECUTOR_ALREADY_SET_IN_DIFFERENT_LEVEL = '43'; // executor address already being used as executor of a different level string public constant INVALID_VOTING_DURATION = '44'; // voting duration can not be bigger than the time it takes to execute a proposal string public constant VOTING_DURATION_NOT_PASSED = '45'; // at least votingDuration should have passed since voting started for a proposal to be queued string public constant INVALID_PROPOSAL_ACCESS_LEVEL = '46'; // the bridged proposal access level does not correspond with the maximum access level required by the payload string public constant PAYLOAD_NOT_CREATED_BEFORE_PROPOSAL = '47'; // payload must be created before proposal string public constant INVALID_CROSS_CHAIN_CONTROLLER_ADDRESS = '48'; string public constant INVALID_MESSAGE_ORIGINATOR_ADDRESS = '49'; string public constant INVALID_ORIGIN_CHAIN_ID = '50'; string public constant INVALID_ACTION_TARGET = '51'; string public constant INVALID_ACTION_ACCESS_LEVEL = '52'; string public constant INVALID_EXECUTOR_ACCESS_LEVEL = '53'; string public constant INVALID_VOTING_PORTAL_CROSS_CHAIN_CONTROLLER = '54'; string public constant INVALID_VOTING_PORTAL_VOTING_MACHINE = '55'; string public constant INVALID_VOTING_PORTAL_GOVERNANCE = '56'; string public constant INVALID_VOTING_MACHINE_CHAIN_ID = '57'; string public constant G_INVALID_CROSS_CHAIN_CONTROLLER_ADDRESS = '58'; string public constant G_INVALID_IPFS_HASH = '59'; string public constant G_INVALID_PAYLOAD_ACCESS_LEVEL = '60'; string public constant G_INVALID_PAYLOADS_CONTROLLER = '61'; string public constant G_INVALID_PAYLOAD_CHAIN = '62'; string public constant POWER_STRATEGY_HAS_NO_TOKENS = '63'; // power strategy should at least have string public constant INVALID_VOTING_CONFIG_ACCESS_LEVEL = '64'; string public constant VOTING_DURATION_TOO_SMALL = '65'; string public constant NO_BRIDGED_VOTING_ASSETS = '66'; string public constant INVALID_VOTER = '67'; string public constant INVALID_DATA_WAREHOUSE = '68'; string public constant INVALID_VOTING_MACHINE_CROSS_CHAIN_CONTROLLER = '69'; string public constant INVALID_L1_VOTING_PORTAL = '70'; string public constant INVALID_VOTING_PORTAL_CHAIN_ID = '71'; string public constant INVALID_VOTING_STRATEGY = '72'; string public constant INVALID_VOTE_CONFIGURATION_BLOCKHASH = '73'; string public constant INVALID_VOTE_CONFIGURATION_VOTING_DURATION = '74'; string public constant INVALID_GAS_LIMIT = '75'; string public constant INVALID_VOTING_CONFIGS = '76'; // a lvl2 voting configuration must be sent to initializer string public constant INVALID_EXECUTOR_DELAY = '77'; string public constant REPEATED_STRATEGY_ASSET = '78'; string public constant EMPTY_ASSET_STORAGE_SLOTS = '79'; string public constant REPEATED_STRATEGY_ASSET_SLOT = '80'; string public constant INVALID_EXECUTION_TARGET = '81'; string public constant MISSING_VOTING_CONFIGURATIONS = '82'; // voting configurations for lvl1 and lvl2 must be included on initialization string public constant INVALID_PROPOSITION_POWER = '83'; string public constant INVALID_YES_THRESHOLD = '84'; string public constant INVALID_YES_NO_DIFFERENTIAL = '85'; string public constant ETH_TRANSFER_FAILED = '86'; string public constant INVALID_INITIAL_VOTING_CONFIGS = '87'; // initial voting configurations can not be of the same level string public constant INVALID_VOTING_PORTAL_ADDRESS_IN_VOTING_MACHINE = '88'; string public constant INVALID_VOTING_PORTAL_OWNER = '89'; string public constant CANCELLATION_FEE_REDEEM_FAILED = '90'; // cancellation fee was not able to be redeemed string public constant INVALID_CANCELLATION_FEE_COLLECTOR = '91'; // collector can not be address 0 string public constant INVALID_CANCELLATION_FEE_SENT = '92'; // cancellation fee sent does not match the needed amount string public constant CANCELLATION_FEE_ALREADY_REDEEMED = '93'; // cancellation fee already redeemed string public constant INVALID_STATE_TO_REDEEM_CANCELLATION_FEE = '94'; // proposal state is not a valid state to redeem cancellation fee string public constant MISSING_REPRESENTATION_ROOTS = '95'; // to represent a voter the representation roots need to be registered string public constant CALLER_IS_NOT_VOTER_REPRESENTATIVE = '96'; // to represent a voter, caller must be the stored representative string public constant VM_INVALID_GOVERNANCE_ADDRESS = '97'; // governance address can not be 0 string public constant ALL_DELEGATION_ACTIONS_FAILED = '98'; // all meta delegation actions failed on MetaDelegateHelper string public constant ONLY_BY_PAYLOADS_MANAGER = '99'; // only payloads manager can call this function string public constant ONLY_BY_PAYLOADS_MANAGER_OR_GUARDIAN = '100'; // only payloads manager or guardian can call this function string public constant FUNCTION_NOT_SUPPORTED = '101'; // function not supported }
// SPDX-License-Identifier: MIT pragma solidity >=0.7.0; import {IWithGuardian} from './interfaces/IWithGuardian.sol'; import {Ownable} from 'openzeppelin-contracts/contracts/access/Ownable.sol'; abstract contract OwnableWithGuardian is Ownable, IWithGuardian { address private _guardian; constructor() Ownable(_msgSender()) { _updateGuardian(_msgSender()); } modifier onlyGuardian() { _checkGuardian(); _; } modifier onlyOwnerOrGuardian() { _checkOwnerOrGuardian(); _; } function guardian() public view override returns (address) { return _guardian; } /// @inheritdoc IWithGuardian function updateGuardian(address newGuardian) external override onlyOwnerOrGuardian { _updateGuardian(newGuardian); } /** * @dev method to update the guardian * @param newGuardian the new guardian address */ function _updateGuardian(address newGuardian) internal { address oldGuardian = _guardian; _guardian = newGuardian; emit GuardianUpdated(oldGuardian, newGuardian); } function _checkGuardian() internal view { require(guardian() == _msgSender(), 'ONLY_BY_GUARDIAN'); } function _checkOwnerOrGuardian() internal view { require(_msgSender() == owner() || _msgSender() == guardian(), 'ONLY_BY_OWNER_OR_GUARDIAN'); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.8; import {IERC20} from 'openzeppelin-contracts/contracts/token/ERC20/IERC20.sol'; import {RescuableBase} from './RescuableBase.sol'; import {IRescuable} from './interfaces/IRescuable.sol'; /** * @title Rescuable * @author BGD Labs * @notice abstract contract with the methods to rescue tokens (ERC20 and native) from a contract */ abstract contract Rescuable is RescuableBase, IRescuable { /// @notice modifier that checks that caller is allowed address modifier onlyRescueGuardian() { if (msg.sender != whoCanRescue()) { revert OnlyRescueGuardian(); } _; } /// @inheritdoc IRescuable function emergencyTokenTransfer( address erc20Token, address to, uint256 amount ) external virtual onlyRescueGuardian { _emergencyTokenTransfer(erc20Token, to, amount); } /// @inheritdoc IRescuable function emergencyEtherTransfer(address to, uint256 amount) external virtual onlyRescueGuardian { _emergencyEtherTransfer(to, amount); } function whoCanRescue() public view virtual returns (address); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.8; import {IRescuableBase} from './IRescuableBase.sol'; /** * @title IRescuable * @author BGD Labs * @notice interface containing the objects, events and methods definitions of the Rescuable contract */ interface IRescuable is IRescuableBase { error OnlyRescueGuardian(); /** * @notice method called to rescue tokens sent erroneously to the contract. Only callable by owner * @param erc20Token address of the token to rescue * @param to address to send the tokens * @param amount of tokens to rescue */ function emergencyTokenTransfer(address erc20Token, address to, uint256 amount) external; /** * @notice method called to rescue ether sent erroneously to the contract. Only callable by owner * @param to address to send the eth * @param amount of eth to rescue */ function emergencyEtherTransfer(address to, uint256 amount) external; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.20; /** * @dev Interface of the ERC-20 standard as defined in the ERC. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the value of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the value of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves a `value` amount of tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 value) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets a `value` amount of tokens as the allowance of `spender` over the * caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 value) external returns (bool); /** * @dev Moves a `value` amount of tokens from `from` to `to` using the * allowance mechanism. `value` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 value) external returns (bool); }
// SPDX-License-Identifier: MIT /** * @dev OpenZeppelin Contracts (last updated v4.7.0) (proxy/utils/Initializable.sol) * From https://github.com/OpenZeppelin/openzeppelin-contracts/tree/8b778fa20d6d76340c5fac1ed66c80273f05b95a * * BGD Labs adaptations: * - Added a constructor disabling initialization for implementation contracts * - Linting */ pragma solidity ^0.8.2; import './Address.sol'; /** * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. * * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be * reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in * case an upgrade adds a module that needs to be initialized. * * For example: * * [.hljs-theme-light.nopadding] * ``` * contract MyToken is ERC20Upgradeable { * function initialize() initializer public { * __ERC20_init("MyToken", "MTK"); * } * } * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable { * function initializeV2() reinitializer(2) public { * __ERC20Permit_init("MyToken"); * } * } * ``` * * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. * * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. * * [CAUTION] * ==== * Avoid leaving a contract uninitialized. * * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed: * * [.hljs-theme-light.nopadding] * ``` * /// @custom:oz-upgrades-unsafe-allow constructor * constructor() { * _disableInitializers(); * } * ``` * ==== */ abstract contract Initializable { /** * @dev Indicates that the contract has been initialized. * @custom:oz-retyped-from bool */ uint8 private _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool private _initializing; /** * @dev Triggered when the contract has been initialized or reinitialized. */ event Initialized(uint8 version); /** * @dev OPINIONATED. Generally is not a good practise to allow initialization of implementations */ constructor() { _disableInitializers(); } /** * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope, * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`. */ modifier initializer() { bool isTopLevelCall = !_initializing; require( (isTopLevelCall && _initialized < 1) || (!Address.isContract(address(this)) && _initialized == 1), 'Initializable: contract is already initialized' ); _initialized = 1; if (isTopLevelCall) { _initializing = true; } _; if (isTopLevelCall) { _initializing = false; emit Initialized(1); } } /** * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be * used to initialize parent contracts. * * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original * initialization step. This is essential to configure modules that are added through upgrades and that require * initialization. * * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in * a contract, executing them in the right order is up to the developer or operator. */ modifier reinitializer(uint8 version) { require( !_initializing && _initialized < version, 'Initializable: contract is already initialized' ); _initialized = version; _initializing = true; _; _initializing = false; emit Initialized(version); } /** * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the * {initializer} and {reinitializer} modifiers, directly or indirectly. */ modifier onlyInitializing() { require(_initializing, 'Initializable: contract is not initializing'); _; } /** * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call. * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized * to any version. It is recommended to use this to lock implementation contracts that are designed to be called * through proxies. */ function _disableInitializers() internal virtual { require(!_initializing, 'Initializable: contract is initializing'); if (_initialized < type(uint8).max) { _initialized = type(uint8).max; emit Initialized(type(uint8).max); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.20; import {IERC20} from "../IERC20.sol"; import {IERC1363} from "../../../interfaces/IERC1363.sol"; import {Address} from "../../../utils/Address.sol"; /** * @title SafeERC20 * @dev Wrappers around ERC-20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { /** * @dev An operation with an ERC-20 token failed. */ error SafeERC20FailedOperation(address token); /** * @dev Indicates a failed `decreaseAllowance` request. */ error SafeERC20FailedDecreaseAllowance(address spender, uint256 currentAllowance, uint256 requestedDecrease); /** * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeTransfer(IERC20 token, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeCall(token.transfer, (to, value))); } /** * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful. */ function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeCall(token.transferFrom, (from, to, value))); } /** * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. * * IMPORTANT: If the token implements ERC-7674 (ERC-20 with temporary allowance), and if the "client" * smart contract uses ERC-7674 to set temporary allowances, then the "client" smart contract should avoid using * this function. Performing a {safeIncreaseAllowance} or {safeDecreaseAllowance} operation on a token contract * that has a non-zero temporary allowance (for that particular owner-spender) will result in unexpected behavior. */ function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 oldAllowance = token.allowance(address(this), spender); forceApprove(token, spender, oldAllowance + value); } /** * @dev Decrease the calling contract's allowance toward `spender` by `requestedDecrease`. If `token` returns no * value, non-reverting calls are assumed to be successful. * * IMPORTANT: If the token implements ERC-7674 (ERC-20 with temporary allowance), and if the "client" * smart contract uses ERC-7674 to set temporary allowances, then the "client" smart contract should avoid using * this function. Performing a {safeIncreaseAllowance} or {safeDecreaseAllowance} operation on a token contract * that has a non-zero temporary allowance (for that particular owner-spender) will result in unexpected behavior. */ function safeDecreaseAllowance(IERC20 token, address spender, uint256 requestedDecrease) internal { unchecked { uint256 currentAllowance = token.allowance(address(this), spender); if (currentAllowance < requestedDecrease) { revert SafeERC20FailedDecreaseAllowance(spender, currentAllowance, requestedDecrease); } forceApprove(token, spender, currentAllowance - requestedDecrease); } } /** * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval * to be set to zero before setting it to a non-zero value, such as USDT. * * NOTE: If the token implements ERC-7674, this function will not modify any temporary allowance. This function * only sets the "standard" allowance. Any temporary allowance will remain active, in addition to the value being * set here. */ function forceApprove(IERC20 token, address spender, uint256 value) internal { bytes memory approvalCall = abi.encodeCall(token.approve, (spender, value)); if (!_callOptionalReturnBool(token, approvalCall)) { _callOptionalReturn(token, abi.encodeCall(token.approve, (spender, 0))); _callOptionalReturn(token, approvalCall); } } /** * @dev Performs an {ERC1363} transferAndCall, with a fallback to the simple {ERC20} transfer if the target has no * code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when * targeting contracts. * * Reverts if the returned value is other than `true`. */ function transferAndCallRelaxed(IERC1363 token, address to, uint256 value, bytes memory data) internal { if (to.code.length == 0) { safeTransfer(token, to, value); } else if (!token.transferAndCall(to, value, data)) { revert SafeERC20FailedOperation(address(token)); } } /** * @dev Performs an {ERC1363} transferFromAndCall, with a fallback to the simple {ERC20} transferFrom if the target * has no code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when * targeting contracts. * * Reverts if the returned value is other than `true`. */ function transferFromAndCallRelaxed( IERC1363 token, address from, address to, uint256 value, bytes memory data ) internal { if (to.code.length == 0) { safeTransferFrom(token, from, to, value); } else if (!token.transferFromAndCall(from, to, value, data)) { revert SafeERC20FailedOperation(address(token)); } } /** * @dev Performs an {ERC1363} approveAndCall, with a fallback to the simple {ERC20} approve if the target has no * code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when * targeting contracts. * * NOTE: When the recipient address (`to`) has no code (i.e. is an EOA), this function behaves as {forceApprove}. * Opposedly, when the recipient address (`to`) has code, this function only attempts to call {ERC1363-approveAndCall} * once without retrying, and relies on the returned value to be true. * * Reverts if the returned value is other than `true`. */ function approveAndCallRelaxed(IERC1363 token, address to, uint256 value, bytes memory data) internal { if (to.code.length == 0) { forceApprove(token, to, value); } else if (!token.approveAndCall(to, value, data)) { revert SafeERC20FailedOperation(address(token)); } } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). * * This is a variant of {_callOptionalReturnBool} that reverts if call fails to meet the requirements. */ function _callOptionalReturn(IERC20 token, bytes memory data) private { uint256 returnSize; uint256 returnValue; assembly ("memory-safe") { let success := call(gas(), token, 0, add(data, 0x20), mload(data), 0, 0x20) // bubble errors if iszero(success) { let ptr := mload(0x40) returndatacopy(ptr, 0, returndatasize()) revert(ptr, returndatasize()) } returnSize := returndatasize() returnValue := mload(0) } if (returnSize == 0 ? address(token).code.length == 0 : returnValue != 1) { revert SafeERC20FailedOperation(address(token)); } } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). * * This is a variant of {_callOptionalReturn} that silently catches all reverts and returns a bool instead. */ function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) { bool success; uint256 returnSize; uint256 returnValue; assembly ("memory-safe") { success := call(gas(), token, 0, add(data, 0x20), mload(data), 0, 0x20) returnSize := returndatasize() returnValue := mload(0) } return success && (returnSize == 0 ? address(token).code.length > 0 : returnValue == 1); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (utils/math/SafeCast.sol) // This file was procedurally generated from scripts/generate/templates/SafeCast.js. pragma solidity ^0.8.20; /** * @dev Wrappers over Solidity's uintXX/intXX/bool casting operators with added overflow * checks. * * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can * easily result in undesired exploitation or bugs, since developers usually * assume that overflows raise errors. `SafeCast` restores this intuition by * reverting the transaction when such an operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. */ library SafeCast { /** * @dev Value doesn't fit in an uint of `bits` size. */ error SafeCastOverflowedUintDowncast(uint8 bits, uint256 value); /** * @dev An int value doesn't fit in an uint of `bits` size. */ error SafeCastOverflowedIntToUint(int256 value); /** * @dev Value doesn't fit in an int of `bits` size. */ error SafeCastOverflowedIntDowncast(uint8 bits, int256 value); /** * @dev An uint value doesn't fit in an int of `bits` size. */ error SafeCastOverflowedUintToInt(uint256 value); /** * @dev Returns the downcasted uint248 from uint256, reverting on * overflow (when the input is greater than largest uint248). * * Counterpart to Solidity's `uint248` operator. * * Requirements: * * - input must fit into 248 bits */ function toUint248(uint256 value) internal pure returns (uint248) { if (value > type(uint248).max) { revert SafeCastOverflowedUintDowncast(248, value); } return uint248(value); } /** * @dev Returns the downcasted uint240 from uint256, reverting on * overflow (when the input is greater than largest uint240). * * Counterpart to Solidity's `uint240` operator. * * Requirements: * * - input must fit into 240 bits */ function toUint240(uint256 value) internal pure returns (uint240) { if (value > type(uint240).max) { revert SafeCastOverflowedUintDowncast(240, value); } return uint240(value); } /** * @dev Returns the downcasted uint232 from uint256, reverting on * overflow (when the input is greater than largest uint232). * * Counterpart to Solidity's `uint232` operator. * * Requirements: * * - input must fit into 232 bits */ function toUint232(uint256 value) internal pure returns (uint232) { if (value > type(uint232).max) { revert SafeCastOverflowedUintDowncast(232, value); } return uint232(value); } /** * @dev Returns the downcasted uint224 from uint256, reverting on * overflow (when the input is greater than largest uint224). * * Counterpart to Solidity's `uint224` operator. * * Requirements: * * - input must fit into 224 bits */ function toUint224(uint256 value) internal pure returns (uint224) { if (value > type(uint224).max) { revert SafeCastOverflowedUintDowncast(224, value); } return uint224(value); } /** * @dev Returns the downcasted uint216 from uint256, reverting on * overflow (when the input is greater than largest uint216). * * Counterpart to Solidity's `uint216` operator. * * Requirements: * * - input must fit into 216 bits */ function toUint216(uint256 value) internal pure returns (uint216) { if (value > type(uint216).max) { revert SafeCastOverflowedUintDowncast(216, value); } return uint216(value); } /** * @dev Returns the downcasted uint208 from uint256, reverting on * overflow (when the input is greater than largest uint208). * * Counterpart to Solidity's `uint208` operator. * * Requirements: * * - input must fit into 208 bits */ function toUint208(uint256 value) internal pure returns (uint208) { if (value > type(uint208).max) { revert SafeCastOverflowedUintDowncast(208, value); } return uint208(value); } /** * @dev Returns the downcasted uint200 from uint256, reverting on * overflow (when the input is greater than largest uint200). * * Counterpart to Solidity's `uint200` operator. * * Requirements: * * - input must fit into 200 bits */ function toUint200(uint256 value) internal pure returns (uint200) { if (value > type(uint200).max) { revert SafeCastOverflowedUintDowncast(200, value); } return uint200(value); } /** * @dev Returns the downcasted uint192 from uint256, reverting on * overflow (when the input is greater than largest uint192). * * Counterpart to Solidity's `uint192` operator. * * Requirements: * * - input must fit into 192 bits */ function toUint192(uint256 value) internal pure returns (uint192) { if (value > type(uint192).max) { revert SafeCastOverflowedUintDowncast(192, value); } return uint192(value); } /** * @dev Returns the downcasted uint184 from uint256, reverting on * overflow (when the input is greater than largest uint184). * * Counterpart to Solidity's `uint184` operator. * * Requirements: * * - input must fit into 184 bits */ function toUint184(uint256 value) internal pure returns (uint184) { if (value > type(uint184).max) { revert SafeCastOverflowedUintDowncast(184, value); } return uint184(value); } /** * @dev Returns the downcasted uint176 from uint256, reverting on * overflow (when the input is greater than largest uint176). * * Counterpart to Solidity's `uint176` operator. * * Requirements: * * - input must fit into 176 bits */ function toUint176(uint256 value) internal pure returns (uint176) { if (value > type(uint176).max) { revert SafeCastOverflowedUintDowncast(176, value); } return uint176(value); } /** * @dev Returns the downcasted uint168 from uint256, reverting on * overflow (when the input is greater than largest uint168). * * Counterpart to Solidity's `uint168` operator. * * Requirements: * * - input must fit into 168 bits */ function toUint168(uint256 value) internal pure returns (uint168) { if (value > type(uint168).max) { revert SafeCastOverflowedUintDowncast(168, value); } return uint168(value); } /** * @dev Returns the downcasted uint160 from uint256, reverting on * overflow (when the input is greater than largest uint160). * * Counterpart to Solidity's `uint160` operator. * * Requirements: * * - input must fit into 160 bits */ function toUint160(uint256 value) internal pure returns (uint160) { if (value > type(uint160).max) { revert SafeCastOverflowedUintDowncast(160, value); } return uint160(value); } /** * @dev Returns the downcasted uint152 from uint256, reverting on * overflow (when the input is greater than largest uint152). * * Counterpart to Solidity's `uint152` operator. * * Requirements: * * - input must fit into 152 bits */ function toUint152(uint256 value) internal pure returns (uint152) { if (value > type(uint152).max) { revert SafeCastOverflowedUintDowncast(152, value); } return uint152(value); } /** * @dev Returns the downcasted uint144 from uint256, reverting on * overflow (when the input is greater than largest uint144). * * Counterpart to Solidity's `uint144` operator. * * Requirements: * * - input must fit into 144 bits */ function toUint144(uint256 value) internal pure returns (uint144) { if (value > type(uint144).max) { revert SafeCastOverflowedUintDowncast(144, value); } return uint144(value); } /** * @dev Returns the downcasted uint136 from uint256, reverting on * overflow (when the input is greater than largest uint136). * * Counterpart to Solidity's `uint136` operator. * * Requirements: * * - input must fit into 136 bits */ function toUint136(uint256 value) internal pure returns (uint136) { if (value > type(uint136).max) { revert SafeCastOverflowedUintDowncast(136, value); } return uint136(value); } /** * @dev Returns the downcasted uint128 from uint256, reverting on * overflow (when the input is greater than largest uint128). * * Counterpart to Solidity's `uint128` operator. * * Requirements: * * - input must fit into 128 bits */ function toUint128(uint256 value) internal pure returns (uint128) { if (value > type(uint128).max) { revert SafeCastOverflowedUintDowncast(128, value); } return uint128(value); } /** * @dev Returns the downcasted uint120 from uint256, reverting on * overflow (when the input is greater than largest uint120). * * Counterpart to Solidity's `uint120` operator. * * Requirements: * * - input must fit into 120 bits */ function toUint120(uint256 value) internal pure returns (uint120) { if (value > type(uint120).max) { revert SafeCastOverflowedUintDowncast(120, value); } return uint120(value); } /** * @dev Returns the downcasted uint112 from uint256, reverting on * overflow (when the input is greater than largest uint112). * * Counterpart to Solidity's `uint112` operator. * * Requirements: * * - input must fit into 112 bits */ function toUint112(uint256 value) internal pure returns (uint112) { if (value > type(uint112).max) { revert SafeCastOverflowedUintDowncast(112, value); } return uint112(value); } /** * @dev Returns the downcasted uint104 from uint256, reverting on * overflow (when the input is greater than largest uint104). * * Counterpart to Solidity's `uint104` operator. * * Requirements: * * - input must fit into 104 bits */ function toUint104(uint256 value) internal pure returns (uint104) { if (value > type(uint104).max) { revert SafeCastOverflowedUintDowncast(104, value); } return uint104(value); } /** * @dev Returns the downcasted uint96 from uint256, reverting on * overflow (when the input is greater than largest uint96). * * Counterpart to Solidity's `uint96` operator. * * Requirements: * * - input must fit into 96 bits */ function toUint96(uint256 value) internal pure returns (uint96) { if (value > type(uint96).max) { revert SafeCastOverflowedUintDowncast(96, value); } return uint96(value); } /** * @dev Returns the downcasted uint88 from uint256, reverting on * overflow (when the input is greater than largest uint88). * * Counterpart to Solidity's `uint88` operator. * * Requirements: * * - input must fit into 88 bits */ function toUint88(uint256 value) internal pure returns (uint88) { if (value > type(uint88).max) { revert SafeCastOverflowedUintDowncast(88, value); } return uint88(value); } /** * @dev Returns the downcasted uint80 from uint256, reverting on * overflow (when the input is greater than largest uint80). * * Counterpart to Solidity's `uint80` operator. * * Requirements: * * - input must fit into 80 bits */ function toUint80(uint256 value) internal pure returns (uint80) { if (value > type(uint80).max) { revert SafeCastOverflowedUintDowncast(80, value); } return uint80(value); } /** * @dev Returns the downcasted uint72 from uint256, reverting on * overflow (when the input is greater than largest uint72). * * Counterpart to Solidity's `uint72` operator. * * Requirements: * * - input must fit into 72 bits */ function toUint72(uint256 value) internal pure returns (uint72) { if (value > type(uint72).max) { revert SafeCastOverflowedUintDowncast(72, value); } return uint72(value); } /** * @dev Returns the downcasted uint64 from uint256, reverting on * overflow (when the input is greater than largest uint64). * * Counterpart to Solidity's `uint64` operator. * * Requirements: * * - input must fit into 64 bits */ function toUint64(uint256 value) internal pure returns (uint64) { if (value > type(uint64).max) { revert SafeCastOverflowedUintDowncast(64, value); } return uint64(value); } /** * @dev Returns the downcasted uint56 from uint256, reverting on * overflow (when the input is greater than largest uint56). * * Counterpart to Solidity's `uint56` operator. * * Requirements: * * - input must fit into 56 bits */ function toUint56(uint256 value) internal pure returns (uint56) { if (value > type(uint56).max) { revert SafeCastOverflowedUintDowncast(56, value); } return uint56(value); } /** * @dev Returns the downcasted uint48 from uint256, reverting on * overflow (when the input is greater than largest uint48). * * Counterpart to Solidity's `uint48` operator. * * Requirements: * * - input must fit into 48 bits */ function toUint48(uint256 value) internal pure returns (uint48) { if (value > type(uint48).max) { revert SafeCastOverflowedUintDowncast(48, value); } return uint48(value); } /** * @dev Returns the downcasted uint40 from uint256, reverting on * overflow (when the input is greater than largest uint40). * * Counterpart to Solidity's `uint40` operator. * * Requirements: * * - input must fit into 40 bits */ function toUint40(uint256 value) internal pure returns (uint40) { if (value > type(uint40).max) { revert SafeCastOverflowedUintDowncast(40, value); } return uint40(value); } /** * @dev Returns the downcasted uint32 from uint256, reverting on * overflow (when the input is greater than largest uint32). * * Counterpart to Solidity's `uint32` operator. * * Requirements: * * - input must fit into 32 bits */ function toUint32(uint256 value) internal pure returns (uint32) { if (value > type(uint32).max) { revert SafeCastOverflowedUintDowncast(32, value); } return uint32(value); } /** * @dev Returns the downcasted uint24 from uint256, reverting on * overflow (when the input is greater than largest uint24). * * Counterpart to Solidity's `uint24` operator. * * Requirements: * * - input must fit into 24 bits */ function toUint24(uint256 value) internal pure returns (uint24) { if (value > type(uint24).max) { revert SafeCastOverflowedUintDowncast(24, value); } return uint24(value); } /** * @dev Returns the downcasted uint16 from uint256, reverting on * overflow (when the input is greater than largest uint16). * * Counterpart to Solidity's `uint16` operator. * * Requirements: * * - input must fit into 16 bits */ function toUint16(uint256 value) internal pure returns (uint16) { if (value > type(uint16).max) { revert SafeCastOverflowedUintDowncast(16, value); } return uint16(value); } /** * @dev Returns the downcasted uint8 from uint256, reverting on * overflow (when the input is greater than largest uint8). * * Counterpart to Solidity's `uint8` operator. * * Requirements: * * - input must fit into 8 bits */ function toUint8(uint256 value) internal pure returns (uint8) { if (value > type(uint8).max) { revert SafeCastOverflowedUintDowncast(8, value); } return uint8(value); } /** * @dev Converts a signed int256 into an unsigned uint256. * * Requirements: * * - input must be greater than or equal to 0. */ function toUint256(int256 value) internal pure returns (uint256) { if (value < 0) { revert SafeCastOverflowedIntToUint(value); } return uint256(value); } /** * @dev Returns the downcasted int248 from int256, reverting on * overflow (when the input is less than smallest int248 or * greater than largest int248). * * Counterpart to Solidity's `int248` operator. * * Requirements: * * - input must fit into 248 bits */ function toInt248(int256 value) internal pure returns (int248 downcasted) { downcasted = int248(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(248, value); } } /** * @dev Returns the downcasted int240 from int256, reverting on * overflow (when the input is less than smallest int240 or * greater than largest int240). * * Counterpart to Solidity's `int240` operator. * * Requirements: * * - input must fit into 240 bits */ function toInt240(int256 value) internal pure returns (int240 downcasted) { downcasted = int240(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(240, value); } } /** * @dev Returns the downcasted int232 from int256, reverting on * overflow (when the input is less than smallest int232 or * greater than largest int232). * * Counterpart to Solidity's `int232` operator. * * Requirements: * * - input must fit into 232 bits */ function toInt232(int256 value) internal pure returns (int232 downcasted) { downcasted = int232(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(232, value); } } /** * @dev Returns the downcasted int224 from int256, reverting on * overflow (when the input is less than smallest int224 or * greater than largest int224). * * Counterpart to Solidity's `int224` operator. * * Requirements: * * - input must fit into 224 bits */ function toInt224(int256 value) internal pure returns (int224 downcasted) { downcasted = int224(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(224, value); } } /** * @dev Returns the downcasted int216 from int256, reverting on * overflow (when the input is less than smallest int216 or * greater than largest int216). * * Counterpart to Solidity's `int216` operator. * * Requirements: * * - input must fit into 216 bits */ function toInt216(int256 value) internal pure returns (int216 downcasted) { downcasted = int216(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(216, value); } } /** * @dev Returns the downcasted int208 from int256, reverting on * overflow (when the input is less than smallest int208 or * greater than largest int208). * * Counterpart to Solidity's `int208` operator. * * Requirements: * * - input must fit into 208 bits */ function toInt208(int256 value) internal pure returns (int208 downcasted) { downcasted = int208(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(208, value); } } /** * @dev Returns the downcasted int200 from int256, reverting on * overflow (when the input is less than smallest int200 or * greater than largest int200). * * Counterpart to Solidity's `int200` operator. * * Requirements: * * - input must fit into 200 bits */ function toInt200(int256 value) internal pure returns (int200 downcasted) { downcasted = int200(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(200, value); } } /** * @dev Returns the downcasted int192 from int256, reverting on * overflow (when the input is less than smallest int192 or * greater than largest int192). * * Counterpart to Solidity's `int192` operator. * * Requirements: * * - input must fit into 192 bits */ function toInt192(int256 value) internal pure returns (int192 downcasted) { downcasted = int192(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(192, value); } } /** * @dev Returns the downcasted int184 from int256, reverting on * overflow (when the input is less than smallest int184 or * greater than largest int184). * * Counterpart to Solidity's `int184` operator. * * Requirements: * * - input must fit into 184 bits */ function toInt184(int256 value) internal pure returns (int184 downcasted) { downcasted = int184(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(184, value); } } /** * @dev Returns the downcasted int176 from int256, reverting on * overflow (when the input is less than smallest int176 or * greater than largest int176). * * Counterpart to Solidity's `int176` operator. * * Requirements: * * - input must fit into 176 bits */ function toInt176(int256 value) internal pure returns (int176 downcasted) { downcasted = int176(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(176, value); } } /** * @dev Returns the downcasted int168 from int256, reverting on * overflow (when the input is less than smallest int168 or * greater than largest int168). * * Counterpart to Solidity's `int168` operator. * * Requirements: * * - input must fit into 168 bits */ function toInt168(int256 value) internal pure returns (int168 downcasted) { downcasted = int168(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(168, value); } } /** * @dev Returns the downcasted int160 from int256, reverting on * overflow (when the input is less than smallest int160 or * greater than largest int160). * * Counterpart to Solidity's `int160` operator. * * Requirements: * * - input must fit into 160 bits */ function toInt160(int256 value) internal pure returns (int160 downcasted) { downcasted = int160(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(160, value); } } /** * @dev Returns the downcasted int152 from int256, reverting on * overflow (when the input is less than smallest int152 or * greater than largest int152). * * Counterpart to Solidity's `int152` operator. * * Requirements: * * - input must fit into 152 bits */ function toInt152(int256 value) internal pure returns (int152 downcasted) { downcasted = int152(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(152, value); } } /** * @dev Returns the downcasted int144 from int256, reverting on * overflow (when the input is less than smallest int144 or * greater than largest int144). * * Counterpart to Solidity's `int144` operator. * * Requirements: * * - input must fit into 144 bits */ function toInt144(int256 value) internal pure returns (int144 downcasted) { downcasted = int144(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(144, value); } } /** * @dev Returns the downcasted int136 from int256, reverting on * overflow (when the input is less than smallest int136 or * greater than largest int136). * * Counterpart to Solidity's `int136` operator. * * Requirements: * * - input must fit into 136 bits */ function toInt136(int256 value) internal pure returns (int136 downcasted) { downcasted = int136(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(136, value); } } /** * @dev Returns the downcasted int128 from int256, reverting on * overflow (when the input is less than smallest int128 or * greater than largest int128). * * Counterpart to Solidity's `int128` operator. * * Requirements: * * - input must fit into 128 bits */ function toInt128(int256 value) internal pure returns (int128 downcasted) { downcasted = int128(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(128, value); } } /** * @dev Returns the downcasted int120 from int256, reverting on * overflow (when the input is less than smallest int120 or * greater than largest int120). * * Counterpart to Solidity's `int120` operator. * * Requirements: * * - input must fit into 120 bits */ function toInt120(int256 value) internal pure returns (int120 downcasted) { downcasted = int120(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(120, value); } } /** * @dev Returns the downcasted int112 from int256, reverting on * overflow (when the input is less than smallest int112 or * greater than largest int112). * * Counterpart to Solidity's `int112` operator. * * Requirements: * * - input must fit into 112 bits */ function toInt112(int256 value) internal pure returns (int112 downcasted) { downcasted = int112(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(112, value); } } /** * @dev Returns the downcasted int104 from int256, reverting on * overflow (when the input is less than smallest int104 or * greater than largest int104). * * Counterpart to Solidity's `int104` operator. * * Requirements: * * - input must fit into 104 bits */ function toInt104(int256 value) internal pure returns (int104 downcasted) { downcasted = int104(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(104, value); } } /** * @dev Returns the downcasted int96 from int256, reverting on * overflow (when the input is less than smallest int96 or * greater than largest int96). * * Counterpart to Solidity's `int96` operator. * * Requirements: * * - input must fit into 96 bits */ function toInt96(int256 value) internal pure returns (int96 downcasted) { downcasted = int96(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(96, value); } } /** * @dev Returns the downcasted int88 from int256, reverting on * overflow (when the input is less than smallest int88 or * greater than largest int88). * * Counterpart to Solidity's `int88` operator. * * Requirements: * * - input must fit into 88 bits */ function toInt88(int256 value) internal pure returns (int88 downcasted) { downcasted = int88(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(88, value); } } /** * @dev Returns the downcasted int80 from int256, reverting on * overflow (when the input is less than smallest int80 or * greater than largest int80). * * Counterpart to Solidity's `int80` operator. * * Requirements: * * - input must fit into 80 bits */ function toInt80(int256 value) internal pure returns (int80 downcasted) { downcasted = int80(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(80, value); } } /** * @dev Returns the downcasted int72 from int256, reverting on * overflow (when the input is less than smallest int72 or * greater than largest int72). * * Counterpart to Solidity's `int72` operator. * * Requirements: * * - input must fit into 72 bits */ function toInt72(int256 value) internal pure returns (int72 downcasted) { downcasted = int72(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(72, value); } } /** * @dev Returns the downcasted int64 from int256, reverting on * overflow (when the input is less than smallest int64 or * greater than largest int64). * * Counterpart to Solidity's `int64` operator. * * Requirements: * * - input must fit into 64 bits */ function toInt64(int256 value) internal pure returns (int64 downcasted) { downcasted = int64(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(64, value); } } /** * @dev Returns the downcasted int56 from int256, reverting on * overflow (when the input is less than smallest int56 or * greater than largest int56). * * Counterpart to Solidity's `int56` operator. * * Requirements: * * - input must fit into 56 bits */ function toInt56(int256 value) internal pure returns (int56 downcasted) { downcasted = int56(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(56, value); } } /** * @dev Returns the downcasted int48 from int256, reverting on * overflow (when the input is less than smallest int48 or * greater than largest int48). * * Counterpart to Solidity's `int48` operator. * * Requirements: * * - input must fit into 48 bits */ function toInt48(int256 value) internal pure returns (int48 downcasted) { downcasted = int48(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(48, value); } } /** * @dev Returns the downcasted int40 from int256, reverting on * overflow (when the input is less than smallest int40 or * greater than largest int40). * * Counterpart to Solidity's `int40` operator. * * Requirements: * * - input must fit into 40 bits */ function toInt40(int256 value) internal pure returns (int40 downcasted) { downcasted = int40(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(40, value); } } /** * @dev Returns the downcasted int32 from int256, reverting on * overflow (when the input is less than smallest int32 or * greater than largest int32). * * Counterpart to Solidity's `int32` operator. * * Requirements: * * - input must fit into 32 bits */ function toInt32(int256 value) internal pure returns (int32 downcasted) { downcasted = int32(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(32, value); } } /** * @dev Returns the downcasted int24 from int256, reverting on * overflow (when the input is less than smallest int24 or * greater than largest int24). * * Counterpart to Solidity's `int24` operator. * * Requirements: * * - input must fit into 24 bits */ function toInt24(int256 value) internal pure returns (int24 downcasted) { downcasted = int24(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(24, value); } } /** * @dev Returns the downcasted int16 from int256, reverting on * overflow (when the input is less than smallest int16 or * greater than largest int16). * * Counterpart to Solidity's `int16` operator. * * Requirements: * * - input must fit into 16 bits */ function toInt16(int256 value) internal pure returns (int16 downcasted) { downcasted = int16(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(16, value); } } /** * @dev Returns the downcasted int8 from int256, reverting on * overflow (when the input is less than smallest int8 or * greater than largest int8). * * Counterpart to Solidity's `int8` operator. * * Requirements: * * - input must fit into 8 bits */ function toInt8(int256 value) internal pure returns (int8 downcasted) { downcasted = int8(value); if (downcasted != value) { revert SafeCastOverflowedIntDowncast(8, value); } } /** * @dev Converts an unsigned uint256 into a signed int256. * * Requirements: * * - input must be less than or equal to maxInt256. */ function toInt256(uint256 value) internal pure returns (int256) { // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive if (value > uint256(type(int256).max)) { revert SafeCastOverflowedUintToInt(value); } return int256(value); } /** * @dev Cast a boolean (false or true) to a uint256 (0 or 1) with no jump. */ function toUint(bool b) internal pure returns (uint256 u) { assembly ("memory-safe") { u := iszero(iszero(b)) } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import {IRescuable} from 'solidity-utils/contracts/utils/interfaces/IRescuable.sol'; import {PayloadsControllerUtils} from '../PayloadsControllerUtils.sol'; /** * @title IPayloadsControllerCore * @author BGD Labs * @notice interface containing the objects, events and methods definitions of the IPayloadsControllerCore contract */ interface IPayloadsControllerCore is IRescuable { /** * @notice Enum indicating the possible payload states * @dev PayloadState enum defines the state machine of a payload, so the order on which the state is defined is important. Check logic correctness if new states are added / removed */ enum PayloadState { None, // state 0 left as empty Created, Queued, Executed, Cancelled, Expired } /** * @notice holds configuration of the executor * @param executor address of the executor * @param delay time in seconds between queuing and execution */ struct ExecutorConfig { address executor; uint40 delay; } /** * @notice Object containing the information necessary to set a new executor * @param accessLevel level of access that the executor will be assigned to * @param executorConfig object containing the configurations for the accessLevel specified */ struct UpdateExecutorInput { PayloadsControllerUtils.AccessControl accessLevel; ExecutorConfig executorConfig; } /** * @notice Object containing the information necessary to define a payload action * @param target address of the contract that needs to be executed * @param withDelegateCall boolean indicating if execution needs to be delegated * @param accessLevel access level of the executor needed for the execution * @param value value amount that needs to be sent to the executeTransaction method * @param signature method signature that will be executed * @param callData data needed for the execution of the signature */ struct ExecutionAction { address target; bool withDelegateCall; PayloadsControllerUtils.AccessControl accessLevel; uint256 value; string signature; bytes callData; } /** * @notice Object containing a payload information * @param creator address of the createPayload method caller * @param maximumAccessLevelRequired min level needed to be able to execute all actions * @param state indicates the current state of the payload * @param createdAt time indicating when payload has been created. In seconds // max is: 1.099511628×10¹² (ie 34'865 years) * @param queuedAt time indicating when payload has been queued. In seconds // max is: 1.099511628×10¹² (ie 34'865 years) * @param executedAt time indicating when a payload has been executed. In seconds // max is: 1.099511628×10¹² (ie 34'865 years) * @param cancelledAt time indicating when the payload has been cancelled. In seconds * @param expirationTime time indicating when the Payload will expire * @param delay time in seconds that a payload must remain queued before execution * @param gracePeriod time in seconds that a payload has to be executed * @param actions array of actions to be executed */ struct Payload { address creator; PayloadsControllerUtils.AccessControl maximumAccessLevelRequired; PayloadState state; uint40 createdAt; uint40 queuedAt; uint40 executedAt; uint40 cancelledAt; uint40 expirationTime; uint40 delay; uint40 gracePeriod; ExecutionAction[] actions; } /** * @notice Event emitted when an executor has been set for a determined access level * @param accessLevel level of access that the executor will be set to * @param executor address that will be set for the determined access level * @param delay time in seconds between queuing and execution */ event ExecutorSet( PayloadsControllerUtils.AccessControl indexed accessLevel, address indexed executor, uint40 delay ); /** * @notice Event emitted when a payload has been created * @param payloadId id of the payload created * @param creator address pertaining to the caller of the method createPayload * @param actions array of the actions conforming the payload * @param maximumAccessLevelRequired maximum level of the access control */ event PayloadCreated( uint40 indexed payloadId, address indexed creator, ExecutionAction[] actions, PayloadsControllerUtils.AccessControl indexed maximumAccessLevelRequired ); /** * @notice emitted when a cross chain message gets received * @param originSender address that sent the message on the origin chain * @param originChainId id of the chain where the message originated * @param delivered flag indicating if message has been delivered * @param message bytes containing the necessary information to queue the bridged payload id * @param reason bytes with the revert information */ event PayloadExecutionMessageReceived( address indexed originSender, uint256 indexed originChainId, bool indexed delivered, bytes message, bytes reason ); /** * @notice Event emitted when a payload has been executed * @param payloadId id of the payload being enqueued */ event PayloadExecuted(uint40 payloadId); /** * @notice Event emitted when a payload has been queued * @param payloadId id of the payload being enqueued */ event PayloadQueued(uint40 payloadId); /** * @notice Event emitted when cancelling a payload * @param payloadId id of the cancelled payload */ event PayloadCancelled(uint40 payloadId); /** * @notice method to initialize the contract with starter params. Only callable by proxy * @param owner address of the owner of the contract. with permissions to call certain methods * @param guardian address of the guardian. With permissions to call certain methods * @param executors array of executor configurations */ function initialize( address owner, address guardian, UpdateExecutorInput[] calldata executors ) external; /** * @notice get the expiration delay of a payload * @return expiration delay in seconds */ function EXPIRATION_DELAY() external view returns (uint40); /** * @notice get the maximum time in seconds that a proposal must spend being queued * @return max delay in seconds */ function MAX_EXECUTION_DELAY() external view returns (uint40); /** * @notice get the minimum time in seconds that a proposal must spend being queued * @return min delay in seconds */ function MIN_EXECUTION_DELAY() external view returns (uint40); /** * @notice time in seconds where the proposal can be executed (from executionTime) before it expires * @return grace period in seconds */ function GRACE_PERIOD() external view returns (uint40); /** * @notice get a previously created payload object * @param payloadId id of the payload to retrieve * @return payload information */ function getPayloadById( uint40 payloadId ) external view returns (Payload memory); /** * @notice get the current state of a payload * @param payloadId id of the payload to retrieve the state from * @return payload state */ function getPayloadState( uint40 payloadId ) external view returns (PayloadState); /** * @notice get the total count of payloads created * @return number of payloads */ function getPayloadsCount() external view returns (uint40); /** * @notice method that will create a Payload object for every action sent * @param actions array of actions which this proposal payload will contain * @return id of the created payload */ function createPayload( ExecutionAction[] calldata actions ) external returns (uint40); /** * @notice method to execute a payload * @param payloadId id of the payload that needs to be executed */ function executePayload(uint40 payloadId) external payable; /** * @notice method to cancel a payload * @param payloadId id of the payload that needs to be canceled */ function cancelPayload(uint40 payloadId) external; /** * @notice method to add executors and its configuration * @param executors array of UpdateExecutorInput objects */ function updateExecutors(UpdateExecutorInput[] calldata executors) external; /** * @notice method to get the executor configuration assigned to the specified level * @param accessControl level of which we want to get the executor configuration from * @return executor configuration */ function getExecutorSettingsByAccessControl( PayloadsControllerUtils.AccessControl accessControl ) external view returns (ExecutorConfig memory); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @title IExecutor * @author BGD Labs * @notice interface containing the objects, events and methods definitions of the Executor contract */ interface IExecutor { /** * @notice emitted when an action got executed * @param target address of the targeted contract * @param value wei value of the transaction * @param signature function signature of the transaction * @param data function arguments of the transaction or callData if signature empty * @param executionTime time at which to execute the transaction * @param withDelegatecall boolean, true = transaction delegatecalls the target, else calls the target * @param resultData the actual callData used on the target **/ event ExecutedAction( address indexed target, uint256 value, string signature, bytes data, uint256 executionTime, bool withDelegatecall, bytes resultData ); /** * @notice Function, called by Governance, that executes a transaction, returns the callData executed * @param target smart contract target * @param value wei value of the transaction * @param signature function signature of the transaction * @param data function arguments of the transaction or callData if signature empty * @param withDelegatecall boolean, true = transaction delegatecalls the target, else calls the target * @return result data of the execution call. **/ function executeTransaction( address target, uint256 value, string memory signature, bytes memory data, bool withDelegatecall ) external payable returns (bytes memory); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @title IBaseReceiverPortal * @author BGD Labs * @notice interface defining the method that needs to be implemented by all receiving portals, as its the one that will be called when a received message gets confirmed */ interface IBaseReceiverPortal { /** * @notice method called by CrossChainController when a message has been confirmed * @param originSender address of the sender of the bridged message * @param originChainId id of the chain where the message originated * @param message bytes bridged containing the desired information */ function receiveCrossChainMessage( address originSender, uint256 originChainId, bytes memory message ) external; }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; library PayloadsControllerUtils { /// @notice enum with supported access levels enum AccessControl { Level_null, // to not use 0 Level_1, // LEVEL_1 - short executor before, listing assets, changes of assets params, updates of the protocol etc Level_2 // LEVEL_2 - long executor before, payloads controller updates } /** * @notice Object containing the necessary payload information. * @param chain * @param accessLevel * @param payloadsController * @param payloadId */ struct Payload { uint256 chain; AccessControl accessLevel; address payloadsController; // address which holds the logic to execute after success proposal voting uint40 payloadId; // number of the payload placed to payloadsController, max is: ~10¹² } }
// SPDX-License-Identifier: MIT pragma solidity >=0.7.0; interface IWithGuardian { /** * @dev Event emitted when guardian gets updated * @param oldGuardian address of previous guardian * @param newGuardian address of the new guardian */ event GuardianUpdated(address oldGuardian, address newGuardian); /** * @dev The caller account is not authorized to perform an operation. */ error OnlyGuardianInvalidCaller(address account); /** * @dev The caller account is not authorized to perform an operation. */ error OnlyGuardianOrOwnerInvalidCaller(address account); /** * @dev get guardian address; */ function guardian() external view returns (address); /** * @dev method to update the guardian * @param newGuardian the new guardian address */ function updateGuardian(address newGuardian) external; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol) pragma solidity ^0.8.20; import {Context} from "../utils/Context.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * The initial owner is set to the address provided by the deployer. This can * later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; /** * @dev The caller account is not authorized to perform an operation. */ error OwnableUnauthorizedAccount(address account); /** * @dev The owner is not a valid owner account. (eg. `address(0)`) */ error OwnableInvalidOwner(address owner); event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the address provided by the deployer as the initial owner. */ constructor(address initialOwner) { if (initialOwner == address(0)) { revert OwnableInvalidOwner(address(0)); } _transferOwnership(initialOwner); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { if (owner() != _msgSender()) { revert OwnableUnauthorizedAccount(_msgSender()); } } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby disabling any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { if (newOwner == address(0)) { revert OwnableInvalidOwner(address(0)); } _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.8; import {IERC20} from 'openzeppelin-contracts/contracts/token/ERC20/IERC20.sol'; import {SafeERC20} from 'openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol'; import {IRescuableBase} from './interfaces/IRescuableBase.sol'; abstract contract RescuableBase is IRescuableBase { using SafeERC20 for IERC20; /// @inheritdoc IRescuableBase function maxRescue(address erc20Token) public view virtual returns (uint256); function _emergencyTokenTransfer(address erc20Token, address to, uint256 amount) internal { uint256 max = maxRescue(erc20Token); amount = max > amount ? amount : max; IERC20(erc20Token).safeTransfer(to, amount); emit ERC20Rescued(msg.sender, erc20Token, to, amount); } function _emergencyEtherTransfer(address to, uint256 amount) internal { (bool success, ) = to.call{value: amount}(new bytes(0)); if (!success) { revert EthTransferFailed(); } emit NativeTokensRescued(msg.sender, to, amount); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.8; /** * @title IRescuableBase * @author BGD Labs * @notice interface containing the objects, events and methods definitions of the RescuableBase contract */ interface IRescuableBase { error EthTransferFailed(); /** * @notice emitted when erc20 tokens get rescued * @param caller address that triggers the rescue * @param token address of the rescued token * @param to address that will receive the rescued tokens * @param amount quantity of tokens rescued */ event ERC20Rescued( address indexed caller, address indexed token, address indexed to, uint256 amount ); /** * @notice emitted when native tokens get rescued * @param caller address that triggers the rescue * @param to address that will receive the rescued tokens * @param amount quantity of tokens rescued */ event NativeTokensRescued(address indexed caller, address indexed to, uint256 amount); /** * @notice method that defined the maximum amount rescuable for any given asset. * @dev there's currently no way to limit the rescuable "native asset", as we assume erc20s as intended underlying. * @return the maximum amount of */ function maxRescue(address erc20Token) external view returns (uint256); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol) // From commit https://github.com/OpenZeppelin/openzeppelin-contracts/commit/8b778fa20d6d76340c5fac1ed66c80273f05b95a pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, 'Address: insufficient balance'); (bool success, ) = recipient.call{value: amount}(''); require(success, 'Address: unable to send value, recipient may have reverted'); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, 'Address: low-level call failed'); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, 'Address: low-level call with value failed'); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, 'Address: insufficient balance for call'); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data ) internal view returns (bytes memory) { return functionStaticCall(target, data, 'Address: low-level static call failed'); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, 'Address: low-level delegate call failed'); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), 'Address: call to non-contract'); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (interfaces/IERC1363.sol) pragma solidity ^0.8.20; import {IERC20} from "./IERC20.sol"; import {IERC165} from "./IERC165.sol"; /** * @title IERC1363 * @dev Interface of the ERC-1363 standard as defined in the https://eips.ethereum.org/EIPS/eip-1363[ERC-1363]. * * Defines an extension interface for ERC-20 tokens that supports executing code on a recipient contract * after `transfer` or `transferFrom`, or code on a spender contract after `approve`, in a single transaction. */ interface IERC1363 is IERC20, IERC165 { /* * Note: the ERC-165 identifier for this interface is 0xb0202a11. * 0xb0202a11 === * bytes4(keccak256('transferAndCall(address,uint256)')) ^ * bytes4(keccak256('transferAndCall(address,uint256,bytes)')) ^ * bytes4(keccak256('transferFromAndCall(address,address,uint256)')) ^ * bytes4(keccak256('transferFromAndCall(address,address,uint256,bytes)')) ^ * bytes4(keccak256('approveAndCall(address,uint256)')) ^ * bytes4(keccak256('approveAndCall(address,uint256,bytes)')) */ /** * @dev Moves a `value` amount of tokens from the caller's account to `to` * and then calls {IERC1363Receiver-onTransferReceived} on `to`. * @param to The address which you want to transfer to. * @param value The amount of tokens to be transferred. * @return A boolean value indicating whether the operation succeeded unless throwing. */ function transferAndCall(address to, uint256 value) external returns (bool); /** * @dev Moves a `value` amount of tokens from the caller's account to `to` * and then calls {IERC1363Receiver-onTransferReceived} on `to`. * @param to The address which you want to transfer to. * @param value The amount of tokens to be transferred. * @param data Additional data with no specified format, sent in call to `to`. * @return A boolean value indicating whether the operation succeeded unless throwing. */ function transferAndCall(address to, uint256 value, bytes calldata data) external returns (bool); /** * @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism * and then calls {IERC1363Receiver-onTransferReceived} on `to`. * @param from The address which you want to send tokens from. * @param to The address which you want to transfer to. * @param value The amount of tokens to be transferred. * @return A boolean value indicating whether the operation succeeded unless throwing. */ function transferFromAndCall(address from, address to, uint256 value) external returns (bool); /** * @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism * and then calls {IERC1363Receiver-onTransferReceived} on `to`. * @param from The address which you want to send tokens from. * @param to The address which you want to transfer to. * @param value The amount of tokens to be transferred. * @param data Additional data with no specified format, sent in call to `to`. * @return A boolean value indicating whether the operation succeeded unless throwing. */ function transferFromAndCall(address from, address to, uint256 value, bytes calldata data) external returns (bool); /** * @dev Sets a `value` amount of tokens as the allowance of `spender` over the * caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`. * @param spender The address which will spend the funds. * @param value The amount of tokens to be spent. * @return A boolean value indicating whether the operation succeeded unless throwing. */ function approveAndCall(address spender, uint256 value) external returns (bool); /** * @dev Sets a `value` amount of tokens as the allowance of `spender` over the * caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`. * @param spender The address which will spend the funds. * @param value The amount of tokens to be spent. * @param data Additional data with no specified format, sent in call to `spender`. * @return A boolean value indicating whether the operation succeeded unless throwing. */ function approveAndCall(address spender, uint256 value, bytes calldata data) external returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (utils/Address.sol) pragma solidity ^0.8.20; import {Errors} from "./Errors.sol"; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev There's no code at `target` (it is not a contract). */ error AddressEmptyCode(address target); /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.8.20/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { if (address(this).balance < amount) { revert Errors.InsufficientBalance(address(this).balance, amount); } (bool success, ) = recipient.call{value: amount}(""); if (!success) { revert Errors.FailedCall(); } } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason or custom error, it is bubbled * up by this function (like regular Solidity function calls). However, if * the call reverted with no returned reason, this function reverts with a * {Errors.FailedCall} error. * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { if (address(this).balance < value) { revert Errors.InsufficientBalance(address(this).balance, value); } (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and reverts if the target * was not a contract or bubbling up the revert reason (falling back to {Errors.FailedCall}) in case * of an unsuccessful call. */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata ) internal view returns (bytes memory) { if (!success) { _revert(returndata); } else { // only check if target is a contract if the call was successful and the return data is empty // otherwise we already know that it was a contract if (returndata.length == 0 && target.code.length == 0) { revert AddressEmptyCode(target); } return returndata; } } /** * @dev Tool to verify that a low level call was successful, and reverts if it wasn't, either by bubbling the * revert reason or with a default {Errors.FailedCall} error. */ function verifyCallResult(bool success, bytes memory returndata) internal pure returns (bytes memory) { if (!success) { _revert(returndata); } else { return returndata; } } /** * @dev Reverts with returndata if present. Otherwise reverts with {Errors.FailedCall}. */ function _revert(bytes memory returndata) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly assembly ("memory-safe") { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert Errors.FailedCall(); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol) pragma solidity ^0.8.20; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } function _contextSuffixLength() internal view virtual returns (uint256) { return 0; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC20.sol) pragma solidity ^0.8.20; import {IERC20} from "../token/ERC20/IERC20.sol";
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC165.sol) pragma solidity ^0.8.20; import {IERC165} from "../utils/introspection/IERC165.sol";
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (utils/Errors.sol) pragma solidity ^0.8.20; /** * @dev Collection of common custom errors used in multiple contracts * * IMPORTANT: Backwards compatibility is not guaranteed in future versions of the library. * It is recommended to avoid relying on the error API for critical functionality. * * _Available since v5.1._ */ library Errors { /** * @dev The ETH balance of the account is not enough to perform the operation. */ error InsufficientBalance(uint256 balance, uint256 needed); /** * @dev A call to an address target failed. The target may have reverted. */ error FailedCall(); /** * @dev The deployment failed. */ error FailedDeployment(); /** * @dev A necessary precompile is missing. */ error MissingPrecompile(address); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (utils/introspection/IERC165.sol) pragma solidity ^0.8.20; /** * @dev Interface of the ERC-165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[ERC]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[ERC section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
{ "remappings": [ "aave-delivery-infrastructure/=lib/adi-deploy/lib/aave-delivery-infrastructure/src/", "solidity-utils/=lib/adi-deploy/lib/aave-delivery-infrastructure/lib/solidity-utils/src/", "forge-std/=lib/adi-deploy/lib/aave-helpers/lib/forge-std/src/", "openzeppelin-contracts/=lib/adi-deploy/lib/aave-delivery-infrastructure/lib/solidity-utils/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/", "aave-helpers/=lib/adi-deploy/lib/aave-helpers/src/", "aave-address-book/=lib/adi-deploy/lib/aave-helpers/lib/aave-address-book/src/", "aave-v3-origin/=lib/adi-deploy/lib/aave-helpers/lib/aave-address-book/lib/aave-v3-origin/src/", "adi-deploy/=lib/adi-deploy/", "@openzeppelin/=lib/adi-deploy/lib/aave-delivery-infrastructure/lib/openzeppelin-contracts/", "@openzeppelin/contracts-upgradeable/=lib/adi-deploy/lib/aave-delivery-infrastructure/lib/solidity-utils/lib/openzeppelin-contracts-upgradeable/contracts/", "@openzeppelin/contracts/=lib/adi-deploy/lib/aave-delivery-infrastructure/lib/solidity-utils/lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/", "aave-v3-origin-tests/=lib/adi-deploy/lib/aave-helpers/lib/aave-address-book/lib/aave-v3-origin/tests/", "adi-scripts/=lib/adi-deploy/lib/aave-delivery-infrastructure/scripts/", "adi-tests/=lib/adi-deploy/lib/aave-delivery-infrastructure/tests/", "adi/=lib/adi-deploy/lib/aave-delivery-infrastructure/src/contracts/", "ds-test/=lib/adi-deploy/lib/aave-delivery-infrastructure/lib/solidity-utils/lib/forge-std/lib/ds-test/src/", "erc4626-tests/=lib/adi-deploy/lib/aave-delivery-infrastructure/lib/openzeppelin-contracts/lib/erc4626-tests/", "halmos-cheatcodes/=lib/adi-deploy/lib/aave-delivery-infrastructure/lib/solidity-utils/lib/openzeppelin-contracts-upgradeable/lib/halmos-cheatcodes/src/", "hyperlane-monorepo/=lib/adi-deploy/lib/aave-delivery-infrastructure/lib/hyperlane-monorepo/solidity/contracts/", "openzeppelin-contracts-upgradeable/=lib/adi-deploy/lib/aave-delivery-infrastructure/lib/solidity-utils/lib/openzeppelin-contracts-upgradeable/", "openzeppelin/=lib/adi-deploy/lib/aave-delivery-infrastructure/lib/openzeppelin-contracts/contracts/" ], "optimizer": { "enabled": true, "runs": 200 }, "metadata": { "useLiteralContent": false, "bytecodeHash": "none", "appendCBOR": true }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "evmVersion": "shanghai", "viaIR": false, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"crossChainController","type":"address"},{"internalType":"address","name":"messageOriginator","type":"address"},{"internalType":"uint256","name":"originChainId","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"EthTransferFailed","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OnlyGuardianInvalidCaller","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OnlyGuardianOrOwnerInvalidCaller","type":"error"},{"inputs":[],"name":"OnlyRescueGuardian","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"SafeERC20FailedOperation","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"caller","type":"address"},{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ERC20Rescued","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"enum PayloadsControllerUtils.AccessControl","name":"accessLevel","type":"uint8"},{"indexed":true,"internalType":"address","name":"executor","type":"address"},{"indexed":false,"internalType":"uint40","name":"delay","type":"uint40"}],"name":"ExecutorSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldGuardian","type":"address"},{"indexed":false,"internalType":"address","name":"newGuardian","type":"address"}],"name":"GuardianUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"caller","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"NativeTokensRescued","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint40","name":"payloadId","type":"uint40"}],"name":"PayloadCancelled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint40","name":"payloadId","type":"uint40"},{"indexed":true,"internalType":"address","name":"creator","type":"address"},{"components":[{"internalType":"address","name":"target","type":"address"},{"internalType":"bool","name":"withDelegateCall","type":"bool"},{"internalType":"enum PayloadsControllerUtils.AccessControl","name":"accessLevel","type":"uint8"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"string","name":"signature","type":"string"},{"internalType":"bytes","name":"callData","type":"bytes"}],"indexed":false,"internalType":"struct IPayloadsControllerCore.ExecutionAction[]","name":"actions","type":"tuple[]"},{"indexed":true,"internalType":"enum PayloadsControllerUtils.AccessControl","name":"maximumAccessLevelRequired","type":"uint8"}],"name":"PayloadCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint40","name":"payloadId","type":"uint40"}],"name":"PayloadExecuted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"originSender","type":"address"},{"indexed":true,"internalType":"uint256","name":"originChainId","type":"uint256"},{"indexed":true,"internalType":"bool","name":"delivered","type":"bool"},{"indexed":false,"internalType":"bytes","name":"message","type":"bytes"},{"indexed":false,"internalType":"bytes","name":"reason","type":"bytes"}],"name":"PayloadExecutionMessageReceived","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint40","name":"payloadId","type":"uint40"}],"name":"PayloadQueued","type":"event"},{"inputs":[],"name":"CROSS_CHAIN_CONTROLLER","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"EXPIRATION_DELAY","outputs":[{"internalType":"uint40","name":"","type":"uint40"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"GRACE_PERIOD","outputs":[{"internalType":"uint40","name":"","type":"uint40"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"MAX_EXECUTION_DELAY","outputs":[{"internalType":"uint40","name":"","type":"uint40"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MESSAGE_ORIGINATOR","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MIN_EXECUTION_DELAY","outputs":[{"internalType":"uint40","name":"","type":"uint40"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ORIGIN_CHAIN_ID","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint40","name":"payloadId","type":"uint40"}],"name":"cancelPayload","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"target","type":"address"},{"internalType":"bool","name":"withDelegateCall","type":"bool"},{"internalType":"enum PayloadsControllerUtils.AccessControl","name":"accessLevel","type":"uint8"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"string","name":"signature","type":"string"},{"internalType":"bytes","name":"callData","type":"bytes"}],"internalType":"struct IPayloadsControllerCore.ExecutionAction[]","name":"actions","type":"tuple[]"}],"name":"createPayload","outputs":[{"internalType":"uint40","name":"","type":"uint40"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"message","type":"bytes"}],"name":"decodeMessage","outputs":[{"internalType":"uint40","name":"","type":"uint40"},{"internalType":"enum PayloadsControllerUtils.AccessControl","name":"","type":"uint8"},{"internalType":"uint40","name":"","type":"uint40"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"emergencyEtherTransfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"erc20Token","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"emergencyTokenTransfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint40","name":"payloadId","type":"uint40"}],"name":"executePayload","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"enum PayloadsControllerUtils.AccessControl","name":"accessControl","type":"uint8"}],"name":"getExecutorSettingsByAccessControl","outputs":[{"components":[{"internalType":"address","name":"executor","type":"address"},{"internalType":"uint40","name":"delay","type":"uint40"}],"internalType":"struct IPayloadsControllerCore.ExecutorConfig","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint40","name":"payloadId","type":"uint40"}],"name":"getPayloadById","outputs":[{"components":[{"internalType":"address","name":"creator","type":"address"},{"internalType":"enum PayloadsControllerUtils.AccessControl","name":"maximumAccessLevelRequired","type":"uint8"},{"internalType":"enum IPayloadsControllerCore.PayloadState","name":"state","type":"uint8"},{"internalType":"uint40","name":"createdAt","type":"uint40"},{"internalType":"uint40","name":"queuedAt","type":"uint40"},{"internalType":"uint40","name":"executedAt","type":"uint40"},{"internalType":"uint40","name":"cancelledAt","type":"uint40"},{"internalType":"uint40","name":"expirationTime","type":"uint40"},{"internalType":"uint40","name":"delay","type":"uint40"},{"internalType":"uint40","name":"gracePeriod","type":"uint40"},{"components":[{"internalType":"address","name":"target","type":"address"},{"internalType":"bool","name":"withDelegateCall","type":"bool"},{"internalType":"enum PayloadsControllerUtils.AccessControl","name":"accessLevel","type":"uint8"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"string","name":"signature","type":"string"},{"internalType":"bytes","name":"callData","type":"bytes"}],"internalType":"struct IPayloadsControllerCore.ExecutionAction[]","name":"actions","type":"tuple[]"}],"internalType":"struct IPayloadsControllerCore.Payload","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint40","name":"payloadId","type":"uint40"}],"name":"getPayloadState","outputs":[{"internalType":"enum IPayloadsControllerCore.PayloadState","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getPayloadsCount","outputs":[{"internalType":"uint40","name":"","type":"uint40"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"guardian","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"guardian","type":"address"},{"components":[{"internalType":"enum PayloadsControllerUtils.AccessControl","name":"accessLevel","type":"uint8"},{"components":[{"internalType":"address","name":"executor","type":"address"},{"internalType":"uint40","name":"delay","type":"uint40"}],"internalType":"struct IPayloadsControllerCore.ExecutorConfig","name":"executorConfig","type":"tuple"}],"internalType":"struct IPayloadsControllerCore.UpdateExecutorInput[]","name":"executors","type":"tuple[]"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"erc20Token","type":"address"}],"name":"maxRescue","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"originSender","type":"address"},{"internalType":"uint256","name":"originChainId","type":"uint256"},{"internalType":"bytes","name":"message","type":"bytes"}],"name":"receiveCrossChainMessage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"enum PayloadsControllerUtils.AccessControl","name":"accessLevel","type":"uint8"},{"components":[{"internalType":"address","name":"executor","type":"address"},{"internalType":"uint40","name":"delay","type":"uint40"}],"internalType":"struct IPayloadsControllerCore.ExecutorConfig","name":"executorConfig","type":"tuple"}],"internalType":"struct IPayloadsControllerCore.UpdateExecutorInput[]","name":"executors","type":"tuple[]"}],"name":"updateExecutors","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newGuardian","type":"address"}],"name":"updateGuardian","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"whoCanRescue","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
60e060405234801562000010575f80fd5b5060405162003bff38038062003bff8339810160408190526200003391620002f2565b33806200005a57604051631e4fbdf760e01b81525f60048201526024015b60405180910390fd5b62000065816200015a565b506200007133620001a9565b6200007b6200020a565b604080518082019091526002815261068760f31b60208201526001600160a01b038416620000be5760405162461bcd60e51b815260040162000051919062000330565b50604080518082019091526002815261343960f01b60208201526001600160a01b038316620001025760405162461bcd60e51b815260040162000051919062000330565b50604080518082019091526002815261035360f41b6020820152816200013d5760405162461bcd60e51b815260040162000051919062000330565b506001600160a01b0392831660a052911660805260c0526200037e565b5f80546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b600180546001600160a01b038381166001600160a01b031983168117909355604080519190921680825260208201939093527f064d28d3d3071c5cbc271a261c10c2f0f0d9e319390397101aa0eb23c6bad909910160405180910390a15050565b600154600160a81b900460ff1615620002765760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840162000051565b60015460ff600160a01b90910481161015620002d4576001805460ff60a01b191660ff60a01b17905560405160ff81527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b80516001600160a01b0381168114620002ed575f80fd5b919050565b5f805f6060848603121562000305575f80fd5b6200031084620002d6565b92506200032060208501620002d6565b9150604084015190509250925092565b5f602080835283518060208501525f5b818110156200035e5785810183015185820160400152820162000340565b505f604082860101526040601f19601f8301168501019250505092915050565b60805160a05160c051613841620003be5f395f81816101b401526105c501525f81816103fa015261055e01525f818161048a015261058801526138415ff3fe608060405260043610610198575f3560e01c8063a4757b0f116100e7578063d740871511610087578063eed88b8d11610062578063eed88b8d146104ac578063f2fde38b146104cb578063f80281fb146104ea578063fc52539514610534575f80fd5b8063d74087151461043b578063e87338941461045a578063eddd795514610479575f80fd5b8063bcbde212116100c2578063bcbde212146103bf578063c1a287e2146103d4578063c4956366146103e9578063d2c4487a1461041c575f80fd5b8063a4757b0f1461031b578063aa30b6ea14610388578063bc03d280146103aa575f80fd5b8063634d45b2116101525780638da5cb5b1161012d5780638da5cb5b1461031b578063910ae3d91461033757806392cdb83414610356578063a3d5b25514610369575f80fd5b8063634d45b2146102ad578063715018a6146102db57806374730f0d146102ef575f80fd5b80630dd85b00146101a357806315034cba146101e95780632c1b77071461020a578063452a932014610231578063568690f41461026257806358007a4e14610281575f80fd5b3661019f57005b5f80fd5b3480156101ae575f80fd5b506101d67f000000000000000000000000000000000000000000000000000000000000000081565b6040519081526020015b60405180910390f35b3480156101f4575f80fd5b50610208610203366004612c56565b610553565b005b348015610215575f80fd5b50622e24805b60405164ffffffffff90911681526020016101e0565b34801561023c575f80fd5b506001546001600160a01b03165b6040516001600160a01b0390911681526020016101e0565b34801561026d575f80fd5b5061020861027c366004612cf1565b610765565b34801561028c575f80fd5b506102a061029b366004612d63565b61092d565b6040516101e09190612ec8565b3480156102b8575f80fd5b506102cc6102c7366004612fc5565b610cb9565b6040516101e093929190612ff6565b3480156102e6575f80fd5b50610208610cdd565b3480156102fa575f80fd5b5061030e610309366004612d63565b610cf0565b6040516101e09190613024565b348015610326575f80fd5b505f546001600160a01b031661024a565b348015610342575f80fd5b50610208610351366004612d63565b610feb565b610208610364366004612d63565b610fff565b348015610374575f80fd5b50610208610383366004613032565b61152e565b348015610393575f80fd5b50600154600160b01b900464ffffffffff1661021b565b3480156103b5575f80fd5b50620d2f0061021b565b3480156103ca575f80fd5b506201518061021b565b3480156103df575f80fd5b5062093a8061021b565b3480156103f4575f80fd5b5061024a7f000000000000000000000000000000000000000000000000000000000000000081565b348015610427575f80fd5b50610208610436366004613070565b611563565b348015610446575f80fd5b506101d66104553660046130ae565b6115bf565b348015610465575f80fd5b5061021b6104743660046130c9565b611627565b348015610484575f80fd5b5061024a7f000000000000000000000000000000000000000000000000000000000000000081565b3480156104b7575f80fd5b506102086104c6366004613137565b611af4565b3480156104d6575f80fd5b506102086104e53660046130ae565b611b28565b3480156104f5575f80fd5b5061050961050436600461316d565b611b62565b6040805182516001600160a01b0316815260209283015164ffffffffff1692810192909252016101e0565b34801561053f575f80fd5b5061020861054e3660046130ae565b611bdd565b336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161480156105bc57507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b0316145b80156105e757507f000000000000000000000000000000000000000000000000000000000000000082145b604051806040016040528060028152602001610c4d60f21b815250906106295760405162461bcd60e51b81526004016106209190613188565b60405180910390fd5b506040516331a6a2d960e11b8152309063634d45b29061064d908490600401613188565b606060405180830381865afa925050508015610686575060408051601f3d908101601f191682019092526106839181019061319a565b60015b610706573d8080156106b3576040519150601f19603f3d011682016040523d82523d5f602084013e6106b8565b606091505b505f151583856001600160a01b03167fc25b8a395435c70772056c57a733c070ec65d7aa03edf1ab08ccd58c51b9082585856040516106f89291906131e4565b60405180910390a450505050565b610711838383611bee565b60606001151586886001600160a01b03167fc25b8a395435c70772056c57a733c070ec65d7aa03edf1ab08ccd58c51b9082588856040516107539291906131e4565b60405180910390a4505050505b505050565b600154600160a81b900460ff161580801561078b575060018054600160a01b900460ff16105b806107ab5750303b1580156107ab575060018054600160a01b900460ff16145b61080e5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610620565b6001805460ff60a01b1916600160a01b179055801561083b576001805460ff60a81b1916600160a81b1790555b604080518082019091526002815261033360f41b6020820152826108725760405162461bcd60e51b81526004016106209190613188565b506108cd8383808060200260200160405190810160405280939291908181526020015f905b828210156108c3576108b460608302860136819003810190613211565b81526020019060010190610897565b5050505050612049565b6108d68461231d565b6108df8561237e565b8015610926576001805460ff60a81b191681556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050505050565b61098b6040805161016081019091525f808252602082019081526020015f81525f602082018190526040820181905260608083018290526080830182905260a0830182905260c0830182905260e08301919091526101009091015290565b64ffffffffff82165f9081526003602090815260408083208151610160810190925280546001600160a01b03811683529192909190830190600160a01b900460ff1660028111156109de576109de612d85565b60028111156109ef576109ef612d85565b81528154602090910190600160a81b900460ff166005811115610a1457610a14612d85565b6005811115610a2557610a25612d85565b8152815464ffffffffff600160b01b82048116602080850191909152600160d81b909204811660408085019190915260018501548083166060860152600160281b810483166080860152600160501b8104831660a0860152600160781b8104831660c0860152600160a01b900490911660e08401526002840180548251818502810185019093528083526101009094019391929091905f9084015b82821015610c74575f8481526020908190206040805160c0810182526004860290920180546001600160a01b038116845260ff600160a01b820481161515958501959095529293909291840191600160a81b9004166002811115610b2657610b26612d85565b6002811115610b3757610b37612d85565b815260200160018201548152602001600282018054610b5590613286565b80601f0160208091040260200160405190810160405280929190818152602001828054610b8190613286565b8015610bcc5780601f10610ba357610100808354040283529160200191610bcc565b820191905f5260205f20905b815481529060010190602001808311610baf57829003601f168201915b50505050508152602001600382018054610be590613286565b80601f0160208091040260200160405190810160405280929190818152602001828054610c1190613286565b8015610c5c5780601f10610c3357610100808354040283529160200191610c5c565b820191905f5260205f20905b815481529060010190602001808311610c3f57829003601f168201915b50505050508152505081526020019060010190610ac0565b50505050815250509050610c87816123cd565b81604001906005811115610c9d57610c9d612d85565b90816005811115610cb057610cb0612d85565b90525092915050565b5f805f83806020019051810190610cd0919061319a565b9250925092509193909250565b610ce561249c565b610cee5f61237e565b565b64ffffffffff81165f9081526003602090815260408083208151610160810190925280546001600160a01b0381168352610fe593830190600160a01b900460ff166002811115610d4257610d42612d85565b6002811115610d5357610d53612d85565b81528154602090910190600160a81b900460ff166005811115610d7857610d78612d85565b6005811115610d8957610d89612d85565b8152815464ffffffffff600160b01b82048116602080850191909152600160d81b909204811660408085019190915260018501548083166060860152600160281b810483166080860152600160501b8104831660a0860152600160781b8104831660c0860152600160a01b900490911660e08401526002840180548251818502810185019093528083526101009094019391929091905f9084015b82821015610fd8575f8481526020908190206040805160c0810182526004860290920180546001600160a01b038116845260ff600160a01b820481161515958501959095529293909291840191600160a81b9004166002811115610e8a57610e8a612d85565b6002811115610e9b57610e9b612d85565b815260200160018201548152602001600282018054610eb990613286565b80601f0160208091040260200160405190810160405280929190818152602001828054610ee590613286565b8015610f305780601f10610f0757610100808354040283529160200191610f30565b820191905f5260205f20905b815481529060010190602001808311610f1357829003601f168201915b50505050508152602001600382018054610f4990613286565b80601f0160208091040260200160405190810160405280929190818152602001828054610f7590613286565b8015610fc05780601f10610f9757610100808354040283529160200191610fc0565b820191905f5260205f20905b815481529060010190602001808311610fa357829003601f168201915b50505050508152505081526020019060010190610e24565b50505050815250506123cd565b92915050565b610ff36124c8565b610ffc81612515565b50565b64ffffffffff81165f908152600360205260409020600260408051610160810190915282546001600160a01b03811682526112ed919084906020830190600160a01b900460ff16600281111561105757611057612d85565b600281111561106857611068612d85565b81528154602090910190600160a81b900460ff16600581111561108d5761108d612d85565b600581111561109e5761109e612d85565b8152815464ffffffffff600160b01b82048116602080850191909152600160d81b909204811660408085019190915260018501548083166060860152600160281b810483166080860152600160501b8104831660a0860152600160781b8104831660c0860152600160a01b900490911660e08401526002840180548251818502810185019093528083526101009094019391929091905f9084015b82821015610fd8575f8481526020908190206040805160c0810182526004860290920180546001600160a01b038116845260ff600160a01b820481161515958501959095529293909291840191600160a81b900416600281111561119f5761119f612d85565b60028111156111b0576111b0612d85565b8152602001600182015481526020016002820180546111ce90613286565b80601f01602080910402602001604051908101604052809291908181526020018280546111fa90613286565b80156112455780601f1061121c57610100808354040283529160200191611245565b820191905f5260205f20905b81548152906001019060200180831161122857829003601f168201915b5050505050815260200160038201805461125e90613286565b80601f016020809104026020016040519081016040528092919081815260200182805461128a90613286565b80156112d55780601f106112ac576101008083540402835291602001916112d5565b820191905f5260205f20905b8154815290600101906020018083116112b857829003601f168201915b50505050508152505081526020019060010190611139565b60058111156112fe576112fe612d85565b1460405180604001604052806002815260200161333360f01b815250906113385760405162461bcd60e51b81526004016106209190613188565b50600181015481545f916113659164ffffffffff600160781b909204821691600160d81b909104166132d2565b64ffffffffff169050804211604051806040016040528060028152602001610ccd60f21b815250906113aa5760405162461bcd60e51b81526004016106209190613188565b50815460ff60a81b1916600360a81b17825560018201805464ffffffffff19164264ffffffffff161790555f5b60028301548110156114ed575f8360020182815481106113f9576113f96132f7565b5f918252602082206004909102018054909250600290829060ff600160a81b909104168281111561142c5761142c612d85565b600281111561143d5761143d612d85565b8152602081019190915260409081015f205460018401548454925163025d36a960e01b81526001600160a01b039283169450849363025d36a99361149f9290821691849160028a019160038b0191600160a01b90910460ff1690600401613384565b5f6040518083038185885af11580156114ba573d5f803e3d5ffd5b50505050506040513d5f823e601f3d908101601f191682016040526114e291908101906133d1565b5050506001016113d7565b5060405164ffffffffff841681527fda6084bb0aa902a7f6da10ba185d4aa129414651c90772417eff02a52112af2a906020015b60405180910390a1505050565b5f546001600160a01b0316331461155857604051633a02626960e01b815260040160405180910390fd5b6107608383836128e0565b61156b61249c565b6115bb8282808060200260200160405190810160405280939291908181526020015f905b828210156108c3576115ac60608302860136819003810190613211565b8152602001906001019061158f565b5050565b6040516370a0823160e01b81523060048201525f906001600160a01b038316906370a0823190602401602060405180830381865afa158015611603573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610fe59190613439565b604080518082019091526002815261333160f01b60208201525f90826116605760405162461bcd60e51b81526004016106209190613188565b50600180545f91600160b01b90910464ffffffffff1690601661168283613450565b82546101009290920a64ffffffffff8181021990931691831602179091558181165f9081526003602052604090208054600161ff0160a01b0319163360ff60a81b191617600160a81b1764ffffffffff60b01b1916600160b01b4293841602178155919250906116f5622e2480836132d2565b60018201805461127560a71b6effffffffff0000000000ffffffffff60501b1990911664ffffffffff93909316600160501b0264ffffffffff60a01b1916929092179190911790555f805b868110156119dd575f88888381811061175b5761175b6132f7565b905060200281019061176d9190613473565b61177b9060208101906130ae565b6001600160a01b0316141560405180604001604052806002815260200161353160f01b815250906117bf5760405162461bcd60e51b81526004016106209190613188565b505f8888838181106117d3576117d36132f7565b90506020028101906117e59190613473565b6117f690606081019060400161316d565b600281111561180757611807612d85565b11604051806040016040528060028152602001611a9960f11b815250906118415760405162461bcd60e51b81526004016106209190613188565b505f6002818a8a85818110611858576118586132f7565b905060200281019061186a9190613473565b61187b90606081019060400161316d565b600281111561188c5761188c612d85565b600281111561189d5761189d612d85565b815260208082019290925260409081015f205481518083019092526002825261199960f11b92820192909252916001600160a01b03909116036118f35760405162461bcd60e51b81526004016106209190613188565b508260020188888381811061190a5761190a6132f7565b905060200281019061191c9190613473565b81546001810183555f928352602090922090916004020161193d828261360a565b505081600281111561195157611951612d85565b888883818110611963576119636132f7565b90506020028101906119759190613473565b61198690606081019060400161316d565b600281111561199757611997612d85565b11156119d5578787828181106119af576119af6132f7565b90506020028101906119c19190613473565b6119d290606081019060400161316d565b91505b600101611740565b5081548190839060ff60a01b1916600160a01b836002811115611a0257611a02612d85565b02179055505f60025f836002811115611a1d57611a1d612d85565b6002811115611a2e57611a2e612d85565b815260208082019290925260409081015f208151808301909252546001600160a01b0381168252600160a01b900464ffffffffff1691810182905260018501805464ffffffffff60781b1916600160781b909302929092179091559050816002811115611a9d57611a9d612d85565b336001600160a01b03168664ffffffffff167f1e4588da4731f84a598f061ee45829a6450aa00aa28962657b6835641afbbac58b8b604051611ae0929190613724565b60405180910390a450929695505050505050565b5f546001600160a01b03163314611b1e57604051633a02626960e01b815260040160405180910390fd5b6115bb8282612960565b611b3061249c565b6001600160a01b038116611b5957604051631e4fbdf760e01b81525f6004820152602401610620565b610ffc8161237e565b604080518082019091525f808252602082015260025f836002811115611b8a57611b8a612d85565b6002811115611b9b57611b9b612d85565b815260208082019290925260409081015f208151808301909252546001600160a01b0381168252600160a01b900464ffffffffff169181019190915292915050565b611be5612a2f565b610ffc8161231d565b64ffffffffff83165f908152600360205260409020600160408051610160810190915282546001600160a01b0381168252611edc919084906020830190600160a01b900460ff166002811115611c4657611c46612d85565b6002811115611c5757611c57612d85565b81528154602090910190600160a81b900460ff166005811115611c7c57611c7c612d85565b6005811115611c8d57611c8d612d85565b8152815464ffffffffff600160b01b82048116602080850191909152600160d81b909204811660408085019190915260018501548083166060860152600160281b810483166080860152600160501b8104831660a0860152600160781b8104831660c0860152600160a01b900490911660e08401526002840180548251818502810185019093528083526101009094019391929091905f9084015b82821015610fd8575f8481526020908190206040805160c0810182526004860290920180546001600160a01b038116845260ff600160a01b820481161515958501959095529293909291840191600160a81b9004166002811115611d8e57611d8e612d85565b6002811115611d9f57611d9f612d85565b815260200160018201548152602001600282018054611dbd90613286565b80601f0160208091040260200160405190810160405280929190818152602001828054611de990613286565b8015611e345780601f10611e0b57610100808354040283529160200191611e34565b820191905f5260205f20905b815481529060010190602001808311611e1757829003601f168201915b50505050508152602001600382018054611e4d90613286565b80601f0160208091040260200160405190810160405280929190818152602001828054611e7990613286565b8015611ec45780601f10611e9b57610100808354040283529160200191611ec4565b820191905f5260205f20905b815481529060010190602001808311611ea757829003601f168201915b50505050508152505081526020019060010190611d28565b6005811115611eed57611eed612d85565b1460405180604001604052806002815260200161199b60f11b81525090611f275760405162461bcd60e51b81526004016106209190613188565b508054600160a01b900460ff166002811115611f4557611f45612d85565b836002811115611f5757611f57612d85565b1015604051806040016040528060028152602001611a1b60f11b81525090611f925760405162461bcd60e51b81526004016106209190613188565b508054604080518082019091526002815261343760f01b60208201529064ffffffffff600160b01b909104811690841611611fe05760405162461bcd60e51b81526004016106209190613188565b508054600160a91b64ffffffffff428116600160d81b02600165ffffffffff0160a81b039093169290921717825560405190851681527f1c4585f98a2bf1a1dca30917ba110f1b978343c7cce2c703495e5e47d51644569060200160405180910390a150505050565b5f5b81518110156115bb575f828281518110612067576120676132f7565b602002602001015190505f6001600160a01b031681602001515f01516001600160a01b03161415604051806040016040528060028152602001611a1960f11b815250906120c75760405162461bcd60e51b81526004016106209190613188565b505f815160028111156120dc576120dc612d85565b1160405180604001604052806002815260200161353360f01b815250906121165760405162461bcd60e51b81526004016106209190613188565b506201518064ffffffffff1681602001516020015164ffffffffff16101580156121595750620d2f0064ffffffffff1681602001516020015164ffffffffff1611155b60405180604001604052806002815260200161373760f01b815250906121925760405162461bcd60e51b81526004016106209190613188565b505f6001825160028111156121a9576121a9612d85565b146121b55760016121b8565b60025b6020830151519091506001600160a01b031660025f83828111156121de576121de612d85565b60028111156121ef576121ef612d85565b815260208082019290925260409081015f205481518083019092526002825261343360f01b92820192909252916001600160a01b03909116036122455760405162461bcd60e51b81526004016106209190613188565b50816020015160025f845f0151600281111561226357612263612d85565b600281111561227457612274612d85565b81526020808201929092526040015f20825181549383015164ffffffffff16600160a01b026001600160c81b03199094166001600160a01b039182161793909317905583015151835191169060028111156122d1576122d1612d85565b60208085015181015160405164ffffffffff90911681527fa7c32b123d845f42a44986cab71b2d81819f15f4478f47d9830a762251372c90910160405180910390a3505060010161204b565b600180546001600160a01b038381166001600160a01b031983168117909355604080519190921680825260208201939093527f064d28d3d3071c5cbc271a261c10c2f0f0d9e319390397101aa0eb23c6bad909910160405180910390a15050565b5f80546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60408101515f90818160058111156123e7576123e7612d85565b14806124055750600381600581111561240257612402612d85565b10155b156124105792915050565b600181600581111561242457612424612d85565b14801561243c57508260e0015164ffffffffff164210155b8061248e5750600281600581111561245657612456612d85565b14801561248e5750826101200151836101000151846080015161247991906132d2565b61248391906132d2565b64ffffffffff164210155b15610fe55750600592915050565b5f546001600160a01b03163314610cee5760405163118cdaa760e01b8152336004820152602401610620565b6001546001600160a01b03163314610cee5760405162461bcd60e51b815260206004820152601060248201526f27a7262cafa12cafa3aaa0a92224a0a760811b6044820152606401610620565b64ffffffffff81165f9081526003602090815260408083208151610160810190925280546001600160a01b038116835290939261280392918591830190600160a01b900460ff16600281111561256d5761256d612d85565b600281111561257e5761257e612d85565b81528154602090910190600160a81b900460ff1660058111156125a3576125a3612d85565b60058111156125b4576125b4612d85565b8152815464ffffffffff600160b01b82048116602080850191909152600160d81b909204811660408085019190915260018501548083166060860152600160281b810483166080860152600160501b8104831660a0860152600160781b8104831660c0860152600160a01b900490911660e08401526002840180548251818502810185019093528083526101009094019391929091905f9084015b82821015610fd8575f8481526020908190206040805160c0810182526004860290920180546001600160a01b038116845260ff600160a01b820481161515958501959095529293909291840191600160a81b90041660028111156126b5576126b5612d85565b60028111156126c6576126c6612d85565b8152602001600182015481526020016002820180546126e490613286565b80601f016020809104026020016040519081016040528092919081815260200182805461271090613286565b801561275b5780601f106127325761010080835404028352916020019161275b565b820191905f5260205f20905b81548152906001019060200180831161273e57829003601f168201915b5050505050815260200160038201805461277490613286565b80601f01602080910402602001604051908101604052809291908181526020018280546127a090613286565b80156127eb5780601f106127c2576101008083540402835291602001916127eb565b820191905f5260205f20905b8154815290600101906020018083116127ce57829003601f168201915b5050505050815250508152602001906001019061264f565b9050600381600581111561281957612819612d85565b1080156128385750600181600581111561283557612835612d85565b10155b60405180604001604052806002815260200161333560f01b815250906128715760405162461bcd60e51b81526004016106209190613188565b50815460ff60a81b1916600160aa1b17825560018201805464ffffffffff428116600160281b0269ffffffffff0000000000199092169190911790915560405190841681527f1f5679387cd5a407876abac64429108734317fc18c0de46eae3cbc0a69a44d5990602001611521565b5f6128ea846115bf565b90508181116128f957806128fb565b815b91506129116001600160a01b0385168484612a9d565b826001600160a01b0316846001600160a01b0316336001600160a01b03167fc7af665d489507e14ae25ac7ab0030fc7f570869610bdd32117ea56b60ae5c61856040516106f891815260200190565b604080515f808252602082019092526001600160a01b0384169083906040516129899190613823565b5f6040518083038185875af1925050503d805f81146129c3576040519150601f19603f3d011682016040523d82523d5f602084013e6129c8565b606091505b50509050806129ea57604051630db2c7f160e31b815260040160405180910390fd5b6040518281526001600160a01b0384169033907fb7c602059992183c7b767c08204223afc99f1895fd175adf9ece23ce9f5bb8b79060200160405180910390a3505050565b5f546001600160a01b0316331480612a5157506001546001600160a01b031633145b610cee5760405162461bcd60e51b815260206004820152601960248201527f4f4e4c595f42595f4f574e45525f4f525f475541524449414e000000000000006044820152606401610620565b604080516001600160a01b03841660248201526044808201849052825180830390910181526064909101909152602080820180516001600160e01b031663a9059cbb60e01b178152825161076093879390925f9283929183919082885af180612b0b576040513d5f823e3d81fd5b50505f513d91508115612b22578060011415612b2f565b6001600160a01b0384163b155b15612b5857604051635274afe760e01b81526001600160a01b0385166004820152602401610620565b50505050565b6001600160a01b0381168114610ffc575f80fd5b634e487b7160e01b5f52604160045260245ffd5b604080519081016001600160401b0381118282101715612ba857612ba8612b72565b60405290565b604051601f8201601f191681016001600160401b0381118282101715612bd657612bd6612b72565b604052919050565b5f6001600160401b03821115612bf657612bf6612b72565b50601f01601f191660200190565b5f82601f830112612c13575f80fd5b8135612c26612c2182612bde565b612bae565b818152846020838601011115612c3a575f80fd5b816020850160208301375f918101602001919091529392505050565b5f805f60608486031215612c68575f80fd5b8335612c7381612b5e565b92506020840135915060408401356001600160401b03811115612c94575f80fd5b612ca086828701612c04565b9150509250925092565b5f8083601f840112612cba575f80fd5b5081356001600160401b03811115612cd0575f80fd5b602083019150836020606083028501011115612cea575f80fd5b9250929050565b5f805f8060608587031215612d04575f80fd5b8435612d0f81612b5e565b93506020850135612d1f81612b5e565b925060408501356001600160401b03811115612d39575f80fd5b612d4587828801612caa565b95989497509550505050565b64ffffffffff81168114610ffc575f80fd5b5f60208284031215612d73575f80fd5b8135612d7e81612d51565b9392505050565b634e487b7160e01b5f52602160045260245ffd5b60038110612da957612da9612d85565b9052565b60068110612da957612da9612d85565b5f5b83811015612dd7578181015183820152602001612dbf565b50505f910152565b5f8151808452612df6816020860160208601612dbd565b601f01601f19169290920160200192915050565b5f82825180855260208086019550808260051b8401018186015f5b84811015612ebb57858303601f19018952815180516001600160a01b031684528481015115158585015260408082015160c09190612e6582880182612d99565b505060608083015181870152506080808301518282880152612e8983880182612ddf565b9250505060a08083015192508582038187015250612ea78183612ddf565b9a86019a9450505090830190600101612e25565b5090979650505050505050565b60208152612ee26020820183516001600160a01b03169052565b5f6020830151612ef56040840182612d99565b506040830151612f086060840182612dad565b50606083015164ffffffffff8116608084015250608083015164ffffffffff811660a08401525060a083015164ffffffffff811660c08401525060c083015164ffffffffff811660e08401525060e0830151610100612f6f8185018364ffffffffff169052565b8401519050610120612f898482018364ffffffffff169052565b8401519050610140612fa38482018364ffffffffff169052565b840151610160848101529050612fbd610180840182612e0a565b949350505050565b5f60208284031215612fd5575f80fd5b81356001600160401b03811115612fea575f80fd5b612fbd84828501612c04565b64ffffffffff848116825260608201906130136020840186612d99565b808416604084015250949350505050565b60208101610fe58284612dad565b5f805f60608486031215613044575f80fd5b833561304f81612b5e565b9250602084013561305f81612b5e565b929592945050506040919091013590565b5f8060208385031215613081575f80fd5b82356001600160401b03811115613096575f80fd5b6130a285828601612caa565b90969095509350505050565b5f602082840312156130be575f80fd5b8135612d7e81612b5e565b5f80602083850312156130da575f80fd5b82356001600160401b03808211156130f0575f80fd5b818501915085601f830112613103575f80fd5b813581811115613111575f80fd5b8660208260051b8501011115613125575f80fd5b60209290920196919550909350505050565b5f8060408385031215613148575f80fd5b823561315381612b5e565b946020939093013593505050565b60038110610ffc575f80fd5b5f6020828403121561317d575f80fd5b8135612d7e81613161565b602081525f612d7e6020830184612ddf565b5f805f606084860312156131ac575f80fd5b83516131b781612d51565b60208501519093506131c881613161565b60408501519092506131d981612d51565b809150509250925092565b604081525f6131f66040830185612ddf565b82810360208401526132088185612ddf565b95945050505050565b5f8183036060811215613222575f80fd5b61322a612b86565b833561323581613161565b81526040601f1983011215613248575f80fd5b613250612b86565b9150602084013561326081612b5e565b8252604084013561327081612d51565b6020838101919091528101919091529392505050565b600181811c9082168061329a57607f821691505b6020821081036132b857634e487b7160e01b5f52602260045260245ffd5b50919050565b634e487b7160e01b5f52601160045260245ffd5b64ffffffffff8181168382160190808211156132f0576132f06132be565b5092915050565b634e487b7160e01b5f52603260045260245ffd5b5f815461331781613286565b808552602060018381168015613334576001811461334e57613379565b60ff1985168884015283151560051b880183019550613379565b865f52825f205f5b858110156133715781548a8201860152908301908401613356565b890184019650505b505050505092915050565b60018060a01b038616815284602082015260a060408201525f6133aa60a083018661330b565b82810360608401526133bc818661330b565b91505082151560808301529695505050505050565b5f602082840312156133e1575f80fd5b81516001600160401b038111156133f6575f80fd5b8201601f81018413613406575f80fd5b8051613414612c2182612bde565b818152856020838501011115613428575f80fd5b613208826020830160208601612dbd565b5f60208284031215613449575f80fd5b5051919050565b5f64ffffffffff808316818103613469576134696132be565b6001019392505050565b5f823560be19833603018112613487575f80fd5b9190910192915050565b8015158114610ffc575f80fd5b600382106134ae576134ae612d85565b805460ff60a81b191660a89290921b60ff60a81b16919091179055565b5f808335601e198436030181126134e0575f80fd5b8301803591506001600160401b038211156134f9575f80fd5b602001915036819003821315612cea575f80fd5b601f82111561076057805f5260205f20601f840160051c810160208510156135325750805b601f840160051c820191505b81811015610926575f815560010161353e565b6001600160401b0383111561356857613568612b72565b61357c836135768354613286565b8361350d565b5f601f8411600181146135ad575f85156135965750838201355b5f19600387901b1c1916600186901b178355610926565b5f83815260208120601f198716915b828110156135dc57868501358255602094850194600190920191016135bc565b50868210156135f8575f1960f88860031b161c19848701351681555b505060018560011b0183555050505050565b813561361581612b5e565b81546001600160a01b031981166001600160a01b03929092169182178355602084013561364181613491565b6001600160a81b03199190911690911790151560a01b60ff60a01b16178155604082013561366e81613161565b613678818361349e565b506060820135600182015561369060808301836134cb565b61369e818360028601613551565b50506136ad60a08301836134cb565b612b58818360038601613551565b5f808335601e198436030181126136d0575f80fd5b83016020810192503590506001600160401b038111156136ee575f80fd5b803603821315612cea575f80fd5b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b60208082528181018390525f906040808401600586901b8501820187855b8881101561381557878303603f190184528135368b900360be19018112613767575f80fd5b8a0160c0813561377681612b5e565b6001600160a01b031685528188013561378e81613491565b151585890152818701356137a181613161565b6137ad88870182612d99565b506060828101359086015260806137c6818401846136bb565b83838901526137d884890182846136fc565b935050505060a06137eb818401846136bb565b9350868303828801526137ff8385836136fc565b978a019796505050928701925050600101613742565b509098975050505050505050565b5f8251613487818460208701612dbd56fea164736f6c6343000816000a00000000000000000000000058e003a3c6f2aeed6a2a6bc77b504566523cb15c0000000000000000000000009aee0b04504cef83a65ac3f0e838d0593bcb2bc70000000000000000000000000000000000000000000000000000000000000001
Deployed Bytecode
0x608060405260043610610198575f3560e01c8063a4757b0f116100e7578063d740871511610087578063eed88b8d11610062578063eed88b8d146104ac578063f2fde38b146104cb578063f80281fb146104ea578063fc52539514610534575f80fd5b8063d74087151461043b578063e87338941461045a578063eddd795514610479575f80fd5b8063bcbde212116100c2578063bcbde212146103bf578063c1a287e2146103d4578063c4956366146103e9578063d2c4487a1461041c575f80fd5b8063a4757b0f1461031b578063aa30b6ea14610388578063bc03d280146103aa575f80fd5b8063634d45b2116101525780638da5cb5b1161012d5780638da5cb5b1461031b578063910ae3d91461033757806392cdb83414610356578063a3d5b25514610369575f80fd5b8063634d45b2146102ad578063715018a6146102db57806374730f0d146102ef575f80fd5b80630dd85b00146101a357806315034cba146101e95780632c1b77071461020a578063452a932014610231578063568690f41461026257806358007a4e14610281575f80fd5b3661019f57005b5f80fd5b3480156101ae575f80fd5b506101d67f000000000000000000000000000000000000000000000000000000000000000181565b6040519081526020015b60405180910390f35b3480156101f4575f80fd5b50610208610203366004612c56565b610553565b005b348015610215575f80fd5b50622e24805b60405164ffffffffff90911681526020016101e0565b34801561023c575f80fd5b506001546001600160a01b03165b6040516001600160a01b0390911681526020016101e0565b34801561026d575f80fd5b5061020861027c366004612cf1565b610765565b34801561028c575f80fd5b506102a061029b366004612d63565b61092d565b6040516101e09190612ec8565b3480156102b8575f80fd5b506102cc6102c7366004612fc5565b610cb9565b6040516101e093929190612ff6565b3480156102e6575f80fd5b50610208610cdd565b3480156102fa575f80fd5b5061030e610309366004612d63565b610cf0565b6040516101e09190613024565b348015610326575f80fd5b505f546001600160a01b031661024a565b348015610342575f80fd5b50610208610351366004612d63565b610feb565b610208610364366004612d63565b610fff565b348015610374575f80fd5b50610208610383366004613032565b61152e565b348015610393575f80fd5b50600154600160b01b900464ffffffffff1661021b565b3480156103b5575f80fd5b50620d2f0061021b565b3480156103ca575f80fd5b506201518061021b565b3480156103df575f80fd5b5062093a8061021b565b3480156103f4575f80fd5b5061024a7f00000000000000000000000058e003a3c6f2aeed6a2a6bc77b504566523cb15c81565b348015610427575f80fd5b50610208610436366004613070565b611563565b348015610446575f80fd5b506101d66104553660046130ae565b6115bf565b348015610465575f80fd5b5061021b6104743660046130c9565b611627565b348015610484575f80fd5b5061024a7f0000000000000000000000009aee0b04504cef83a65ac3f0e838d0593bcb2bc781565b3480156104b7575f80fd5b506102086104c6366004613137565b611af4565b3480156104d6575f80fd5b506102086104e53660046130ae565b611b28565b3480156104f5575f80fd5b5061050961050436600461316d565b611b62565b6040805182516001600160a01b0316815260209283015164ffffffffff1692810192909252016101e0565b34801561053f575f80fd5b5061020861054e3660046130ae565b611bdd565b336001600160a01b037f00000000000000000000000058e003a3c6f2aeed6a2a6bc77b504566523cb15c161480156105bc57507f0000000000000000000000009aee0b04504cef83a65ac3f0e838d0593bcb2bc76001600160a01b0316836001600160a01b0316145b80156105e757507f000000000000000000000000000000000000000000000000000000000000000182145b604051806040016040528060028152602001610c4d60f21b815250906106295760405162461bcd60e51b81526004016106209190613188565b60405180910390fd5b506040516331a6a2d960e11b8152309063634d45b29061064d908490600401613188565b606060405180830381865afa925050508015610686575060408051601f3d908101601f191682019092526106839181019061319a565b60015b610706573d8080156106b3576040519150601f19603f3d011682016040523d82523d5f602084013e6106b8565b606091505b505f151583856001600160a01b03167fc25b8a395435c70772056c57a733c070ec65d7aa03edf1ab08ccd58c51b9082585856040516106f89291906131e4565b60405180910390a450505050565b610711838383611bee565b60606001151586886001600160a01b03167fc25b8a395435c70772056c57a733c070ec65d7aa03edf1ab08ccd58c51b9082588856040516107539291906131e4565b60405180910390a4505050505b505050565b600154600160a81b900460ff161580801561078b575060018054600160a01b900460ff16105b806107ab5750303b1580156107ab575060018054600160a01b900460ff16145b61080e5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610620565b6001805460ff60a01b1916600160a01b179055801561083b576001805460ff60a81b1916600160a81b1790555b604080518082019091526002815261033360f41b6020820152826108725760405162461bcd60e51b81526004016106209190613188565b506108cd8383808060200260200160405190810160405280939291908181526020015f905b828210156108c3576108b460608302860136819003810190613211565b81526020019060010190610897565b5050505050612049565b6108d68461231d565b6108df8561237e565b8015610926576001805460ff60a81b191681556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050505050565b61098b6040805161016081019091525f808252602082019081526020015f81525f602082018190526040820181905260608083018290526080830182905260a0830182905260c0830182905260e08301919091526101009091015290565b64ffffffffff82165f9081526003602090815260408083208151610160810190925280546001600160a01b03811683529192909190830190600160a01b900460ff1660028111156109de576109de612d85565b60028111156109ef576109ef612d85565b81528154602090910190600160a81b900460ff166005811115610a1457610a14612d85565b6005811115610a2557610a25612d85565b8152815464ffffffffff600160b01b82048116602080850191909152600160d81b909204811660408085019190915260018501548083166060860152600160281b810483166080860152600160501b8104831660a0860152600160781b8104831660c0860152600160a01b900490911660e08401526002840180548251818502810185019093528083526101009094019391929091905f9084015b82821015610c74575f8481526020908190206040805160c0810182526004860290920180546001600160a01b038116845260ff600160a01b820481161515958501959095529293909291840191600160a81b9004166002811115610b2657610b26612d85565b6002811115610b3757610b37612d85565b815260200160018201548152602001600282018054610b5590613286565b80601f0160208091040260200160405190810160405280929190818152602001828054610b8190613286565b8015610bcc5780601f10610ba357610100808354040283529160200191610bcc565b820191905f5260205f20905b815481529060010190602001808311610baf57829003601f168201915b50505050508152602001600382018054610be590613286565b80601f0160208091040260200160405190810160405280929190818152602001828054610c1190613286565b8015610c5c5780601f10610c3357610100808354040283529160200191610c5c565b820191905f5260205f20905b815481529060010190602001808311610c3f57829003601f168201915b50505050508152505081526020019060010190610ac0565b50505050815250509050610c87816123cd565b81604001906005811115610c9d57610c9d612d85565b90816005811115610cb057610cb0612d85565b90525092915050565b5f805f83806020019051810190610cd0919061319a565b9250925092509193909250565b610ce561249c565b610cee5f61237e565b565b64ffffffffff81165f9081526003602090815260408083208151610160810190925280546001600160a01b0381168352610fe593830190600160a01b900460ff166002811115610d4257610d42612d85565b6002811115610d5357610d53612d85565b81528154602090910190600160a81b900460ff166005811115610d7857610d78612d85565b6005811115610d8957610d89612d85565b8152815464ffffffffff600160b01b82048116602080850191909152600160d81b909204811660408085019190915260018501548083166060860152600160281b810483166080860152600160501b8104831660a0860152600160781b8104831660c0860152600160a01b900490911660e08401526002840180548251818502810185019093528083526101009094019391929091905f9084015b82821015610fd8575f8481526020908190206040805160c0810182526004860290920180546001600160a01b038116845260ff600160a01b820481161515958501959095529293909291840191600160a81b9004166002811115610e8a57610e8a612d85565b6002811115610e9b57610e9b612d85565b815260200160018201548152602001600282018054610eb990613286565b80601f0160208091040260200160405190810160405280929190818152602001828054610ee590613286565b8015610f305780601f10610f0757610100808354040283529160200191610f30565b820191905f5260205f20905b815481529060010190602001808311610f1357829003601f168201915b50505050508152602001600382018054610f4990613286565b80601f0160208091040260200160405190810160405280929190818152602001828054610f7590613286565b8015610fc05780601f10610f9757610100808354040283529160200191610fc0565b820191905f5260205f20905b815481529060010190602001808311610fa357829003601f168201915b50505050508152505081526020019060010190610e24565b50505050815250506123cd565b92915050565b610ff36124c8565b610ffc81612515565b50565b64ffffffffff81165f908152600360205260409020600260408051610160810190915282546001600160a01b03811682526112ed919084906020830190600160a01b900460ff16600281111561105757611057612d85565b600281111561106857611068612d85565b81528154602090910190600160a81b900460ff16600581111561108d5761108d612d85565b600581111561109e5761109e612d85565b8152815464ffffffffff600160b01b82048116602080850191909152600160d81b909204811660408085019190915260018501548083166060860152600160281b810483166080860152600160501b8104831660a0860152600160781b8104831660c0860152600160a01b900490911660e08401526002840180548251818502810185019093528083526101009094019391929091905f9084015b82821015610fd8575f8481526020908190206040805160c0810182526004860290920180546001600160a01b038116845260ff600160a01b820481161515958501959095529293909291840191600160a81b900416600281111561119f5761119f612d85565b60028111156111b0576111b0612d85565b8152602001600182015481526020016002820180546111ce90613286565b80601f01602080910402602001604051908101604052809291908181526020018280546111fa90613286565b80156112455780601f1061121c57610100808354040283529160200191611245565b820191905f5260205f20905b81548152906001019060200180831161122857829003601f168201915b5050505050815260200160038201805461125e90613286565b80601f016020809104026020016040519081016040528092919081815260200182805461128a90613286565b80156112d55780601f106112ac576101008083540402835291602001916112d5565b820191905f5260205f20905b8154815290600101906020018083116112b857829003601f168201915b50505050508152505081526020019060010190611139565b60058111156112fe576112fe612d85565b1460405180604001604052806002815260200161333360f01b815250906113385760405162461bcd60e51b81526004016106209190613188565b50600181015481545f916113659164ffffffffff600160781b909204821691600160d81b909104166132d2565b64ffffffffff169050804211604051806040016040528060028152602001610ccd60f21b815250906113aa5760405162461bcd60e51b81526004016106209190613188565b50815460ff60a81b1916600360a81b17825560018201805464ffffffffff19164264ffffffffff161790555f5b60028301548110156114ed575f8360020182815481106113f9576113f96132f7565b5f918252602082206004909102018054909250600290829060ff600160a81b909104168281111561142c5761142c612d85565b600281111561143d5761143d612d85565b8152602081019190915260409081015f205460018401548454925163025d36a960e01b81526001600160a01b039283169450849363025d36a99361149f9290821691849160028a019160038b0191600160a01b90910460ff1690600401613384565b5f6040518083038185885af11580156114ba573d5f803e3d5ffd5b50505050506040513d5f823e601f3d908101601f191682016040526114e291908101906133d1565b5050506001016113d7565b5060405164ffffffffff841681527fda6084bb0aa902a7f6da10ba185d4aa129414651c90772417eff02a52112af2a906020015b60405180910390a1505050565b5f546001600160a01b0316331461155857604051633a02626960e01b815260040160405180910390fd5b6107608383836128e0565b61156b61249c565b6115bb8282808060200260200160405190810160405280939291908181526020015f905b828210156108c3576115ac60608302860136819003810190613211565b8152602001906001019061158f565b5050565b6040516370a0823160e01b81523060048201525f906001600160a01b038316906370a0823190602401602060405180830381865afa158015611603573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610fe59190613439565b604080518082019091526002815261333160f01b60208201525f90826116605760405162461bcd60e51b81526004016106209190613188565b50600180545f91600160b01b90910464ffffffffff1690601661168283613450565b82546101009290920a64ffffffffff8181021990931691831602179091558181165f9081526003602052604090208054600161ff0160a01b0319163360ff60a81b191617600160a81b1764ffffffffff60b01b1916600160b01b4293841602178155919250906116f5622e2480836132d2565b60018201805461127560a71b6effffffffff0000000000ffffffffff60501b1990911664ffffffffff93909316600160501b0264ffffffffff60a01b1916929092179190911790555f805b868110156119dd575f88888381811061175b5761175b6132f7565b905060200281019061176d9190613473565b61177b9060208101906130ae565b6001600160a01b0316141560405180604001604052806002815260200161353160f01b815250906117bf5760405162461bcd60e51b81526004016106209190613188565b505f8888838181106117d3576117d36132f7565b90506020028101906117e59190613473565b6117f690606081019060400161316d565b600281111561180757611807612d85565b11604051806040016040528060028152602001611a9960f11b815250906118415760405162461bcd60e51b81526004016106209190613188565b505f6002818a8a85818110611858576118586132f7565b905060200281019061186a9190613473565b61187b90606081019060400161316d565b600281111561188c5761188c612d85565b600281111561189d5761189d612d85565b815260208082019290925260409081015f205481518083019092526002825261199960f11b92820192909252916001600160a01b03909116036118f35760405162461bcd60e51b81526004016106209190613188565b508260020188888381811061190a5761190a6132f7565b905060200281019061191c9190613473565b81546001810183555f928352602090922090916004020161193d828261360a565b505081600281111561195157611951612d85565b888883818110611963576119636132f7565b90506020028101906119759190613473565b61198690606081019060400161316d565b600281111561199757611997612d85565b11156119d5578787828181106119af576119af6132f7565b90506020028101906119c19190613473565b6119d290606081019060400161316d565b91505b600101611740565b5081548190839060ff60a01b1916600160a01b836002811115611a0257611a02612d85565b02179055505f60025f836002811115611a1d57611a1d612d85565b6002811115611a2e57611a2e612d85565b815260208082019290925260409081015f208151808301909252546001600160a01b0381168252600160a01b900464ffffffffff1691810182905260018501805464ffffffffff60781b1916600160781b909302929092179091559050816002811115611a9d57611a9d612d85565b336001600160a01b03168664ffffffffff167f1e4588da4731f84a598f061ee45829a6450aa00aa28962657b6835641afbbac58b8b604051611ae0929190613724565b60405180910390a450929695505050505050565b5f546001600160a01b03163314611b1e57604051633a02626960e01b815260040160405180910390fd5b6115bb8282612960565b611b3061249c565b6001600160a01b038116611b5957604051631e4fbdf760e01b81525f6004820152602401610620565b610ffc8161237e565b604080518082019091525f808252602082015260025f836002811115611b8a57611b8a612d85565b6002811115611b9b57611b9b612d85565b815260208082019290925260409081015f208151808301909252546001600160a01b0381168252600160a01b900464ffffffffff169181019190915292915050565b611be5612a2f565b610ffc8161231d565b64ffffffffff83165f908152600360205260409020600160408051610160810190915282546001600160a01b0381168252611edc919084906020830190600160a01b900460ff166002811115611c4657611c46612d85565b6002811115611c5757611c57612d85565b81528154602090910190600160a81b900460ff166005811115611c7c57611c7c612d85565b6005811115611c8d57611c8d612d85565b8152815464ffffffffff600160b01b82048116602080850191909152600160d81b909204811660408085019190915260018501548083166060860152600160281b810483166080860152600160501b8104831660a0860152600160781b8104831660c0860152600160a01b900490911660e08401526002840180548251818502810185019093528083526101009094019391929091905f9084015b82821015610fd8575f8481526020908190206040805160c0810182526004860290920180546001600160a01b038116845260ff600160a01b820481161515958501959095529293909291840191600160a81b9004166002811115611d8e57611d8e612d85565b6002811115611d9f57611d9f612d85565b815260200160018201548152602001600282018054611dbd90613286565b80601f0160208091040260200160405190810160405280929190818152602001828054611de990613286565b8015611e345780601f10611e0b57610100808354040283529160200191611e34565b820191905f5260205f20905b815481529060010190602001808311611e1757829003601f168201915b50505050508152602001600382018054611e4d90613286565b80601f0160208091040260200160405190810160405280929190818152602001828054611e7990613286565b8015611ec45780601f10611e9b57610100808354040283529160200191611ec4565b820191905f5260205f20905b815481529060010190602001808311611ea757829003601f168201915b50505050508152505081526020019060010190611d28565b6005811115611eed57611eed612d85565b1460405180604001604052806002815260200161199b60f11b81525090611f275760405162461bcd60e51b81526004016106209190613188565b508054600160a01b900460ff166002811115611f4557611f45612d85565b836002811115611f5757611f57612d85565b1015604051806040016040528060028152602001611a1b60f11b81525090611f925760405162461bcd60e51b81526004016106209190613188565b508054604080518082019091526002815261343760f01b60208201529064ffffffffff600160b01b909104811690841611611fe05760405162461bcd60e51b81526004016106209190613188565b508054600160a91b64ffffffffff428116600160d81b02600165ffffffffff0160a81b039093169290921717825560405190851681527f1c4585f98a2bf1a1dca30917ba110f1b978343c7cce2c703495e5e47d51644569060200160405180910390a150505050565b5f5b81518110156115bb575f828281518110612067576120676132f7565b602002602001015190505f6001600160a01b031681602001515f01516001600160a01b03161415604051806040016040528060028152602001611a1960f11b815250906120c75760405162461bcd60e51b81526004016106209190613188565b505f815160028111156120dc576120dc612d85565b1160405180604001604052806002815260200161353360f01b815250906121165760405162461bcd60e51b81526004016106209190613188565b506201518064ffffffffff1681602001516020015164ffffffffff16101580156121595750620d2f0064ffffffffff1681602001516020015164ffffffffff1611155b60405180604001604052806002815260200161373760f01b815250906121925760405162461bcd60e51b81526004016106209190613188565b505f6001825160028111156121a9576121a9612d85565b146121b55760016121b8565b60025b6020830151519091506001600160a01b031660025f83828111156121de576121de612d85565b60028111156121ef576121ef612d85565b815260208082019290925260409081015f205481518083019092526002825261343360f01b92820192909252916001600160a01b03909116036122455760405162461bcd60e51b81526004016106209190613188565b50816020015160025f845f0151600281111561226357612263612d85565b600281111561227457612274612d85565b81526020808201929092526040015f20825181549383015164ffffffffff16600160a01b026001600160c81b03199094166001600160a01b039182161793909317905583015151835191169060028111156122d1576122d1612d85565b60208085015181015160405164ffffffffff90911681527fa7c32b123d845f42a44986cab71b2d81819f15f4478f47d9830a762251372c90910160405180910390a3505060010161204b565b600180546001600160a01b038381166001600160a01b031983168117909355604080519190921680825260208201939093527f064d28d3d3071c5cbc271a261c10c2f0f0d9e319390397101aa0eb23c6bad909910160405180910390a15050565b5f80546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60408101515f90818160058111156123e7576123e7612d85565b14806124055750600381600581111561240257612402612d85565b10155b156124105792915050565b600181600581111561242457612424612d85565b14801561243c57508260e0015164ffffffffff164210155b8061248e5750600281600581111561245657612456612d85565b14801561248e5750826101200151836101000151846080015161247991906132d2565b61248391906132d2565b64ffffffffff164210155b15610fe55750600592915050565b5f546001600160a01b03163314610cee5760405163118cdaa760e01b8152336004820152602401610620565b6001546001600160a01b03163314610cee5760405162461bcd60e51b815260206004820152601060248201526f27a7262cafa12cafa3aaa0a92224a0a760811b6044820152606401610620565b64ffffffffff81165f9081526003602090815260408083208151610160810190925280546001600160a01b038116835290939261280392918591830190600160a01b900460ff16600281111561256d5761256d612d85565b600281111561257e5761257e612d85565b81528154602090910190600160a81b900460ff1660058111156125a3576125a3612d85565b60058111156125b4576125b4612d85565b8152815464ffffffffff600160b01b82048116602080850191909152600160d81b909204811660408085019190915260018501548083166060860152600160281b810483166080860152600160501b8104831660a0860152600160781b8104831660c0860152600160a01b900490911660e08401526002840180548251818502810185019093528083526101009094019391929091905f9084015b82821015610fd8575f8481526020908190206040805160c0810182526004860290920180546001600160a01b038116845260ff600160a01b820481161515958501959095529293909291840191600160a81b90041660028111156126b5576126b5612d85565b60028111156126c6576126c6612d85565b8152602001600182015481526020016002820180546126e490613286565b80601f016020809104026020016040519081016040528092919081815260200182805461271090613286565b801561275b5780601f106127325761010080835404028352916020019161275b565b820191905f5260205f20905b81548152906001019060200180831161273e57829003601f168201915b5050505050815260200160038201805461277490613286565b80601f01602080910402602001604051908101604052809291908181526020018280546127a090613286565b80156127eb5780601f106127c2576101008083540402835291602001916127eb565b820191905f5260205f20905b8154815290600101906020018083116127ce57829003601f168201915b5050505050815250508152602001906001019061264f565b9050600381600581111561281957612819612d85565b1080156128385750600181600581111561283557612835612d85565b10155b60405180604001604052806002815260200161333560f01b815250906128715760405162461bcd60e51b81526004016106209190613188565b50815460ff60a81b1916600160aa1b17825560018201805464ffffffffff428116600160281b0269ffffffffff0000000000199092169190911790915560405190841681527f1f5679387cd5a407876abac64429108734317fc18c0de46eae3cbc0a69a44d5990602001611521565b5f6128ea846115bf565b90508181116128f957806128fb565b815b91506129116001600160a01b0385168484612a9d565b826001600160a01b0316846001600160a01b0316336001600160a01b03167fc7af665d489507e14ae25ac7ab0030fc7f570869610bdd32117ea56b60ae5c61856040516106f891815260200190565b604080515f808252602082019092526001600160a01b0384169083906040516129899190613823565b5f6040518083038185875af1925050503d805f81146129c3576040519150601f19603f3d011682016040523d82523d5f602084013e6129c8565b606091505b50509050806129ea57604051630db2c7f160e31b815260040160405180910390fd5b6040518281526001600160a01b0384169033907fb7c602059992183c7b767c08204223afc99f1895fd175adf9ece23ce9f5bb8b79060200160405180910390a3505050565b5f546001600160a01b0316331480612a5157506001546001600160a01b031633145b610cee5760405162461bcd60e51b815260206004820152601960248201527f4f4e4c595f42595f4f574e45525f4f525f475541524449414e000000000000006044820152606401610620565b604080516001600160a01b03841660248201526044808201849052825180830390910181526064909101909152602080820180516001600160e01b031663a9059cbb60e01b178152825161076093879390925f9283929183919082885af180612b0b576040513d5f823e3d81fd5b50505f513d91508115612b22578060011415612b2f565b6001600160a01b0384163b155b15612b5857604051635274afe760e01b81526001600160a01b0385166004820152602401610620565b50505050565b6001600160a01b0381168114610ffc575f80fd5b634e487b7160e01b5f52604160045260245ffd5b604080519081016001600160401b0381118282101715612ba857612ba8612b72565b60405290565b604051601f8201601f191681016001600160401b0381118282101715612bd657612bd6612b72565b604052919050565b5f6001600160401b03821115612bf657612bf6612b72565b50601f01601f191660200190565b5f82601f830112612c13575f80fd5b8135612c26612c2182612bde565b612bae565b818152846020838601011115612c3a575f80fd5b816020850160208301375f918101602001919091529392505050565b5f805f60608486031215612c68575f80fd5b8335612c7381612b5e565b92506020840135915060408401356001600160401b03811115612c94575f80fd5b612ca086828701612c04565b9150509250925092565b5f8083601f840112612cba575f80fd5b5081356001600160401b03811115612cd0575f80fd5b602083019150836020606083028501011115612cea575f80fd5b9250929050565b5f805f8060608587031215612d04575f80fd5b8435612d0f81612b5e565b93506020850135612d1f81612b5e565b925060408501356001600160401b03811115612d39575f80fd5b612d4587828801612caa565b95989497509550505050565b64ffffffffff81168114610ffc575f80fd5b5f60208284031215612d73575f80fd5b8135612d7e81612d51565b9392505050565b634e487b7160e01b5f52602160045260245ffd5b60038110612da957612da9612d85565b9052565b60068110612da957612da9612d85565b5f5b83811015612dd7578181015183820152602001612dbf565b50505f910152565b5f8151808452612df6816020860160208601612dbd565b601f01601f19169290920160200192915050565b5f82825180855260208086019550808260051b8401018186015f5b84811015612ebb57858303601f19018952815180516001600160a01b031684528481015115158585015260408082015160c09190612e6582880182612d99565b505060608083015181870152506080808301518282880152612e8983880182612ddf565b9250505060a08083015192508582038187015250612ea78183612ddf565b9a86019a9450505090830190600101612e25565b5090979650505050505050565b60208152612ee26020820183516001600160a01b03169052565b5f6020830151612ef56040840182612d99565b506040830151612f086060840182612dad565b50606083015164ffffffffff8116608084015250608083015164ffffffffff811660a08401525060a083015164ffffffffff811660c08401525060c083015164ffffffffff811660e08401525060e0830151610100612f6f8185018364ffffffffff169052565b8401519050610120612f898482018364ffffffffff169052565b8401519050610140612fa38482018364ffffffffff169052565b840151610160848101529050612fbd610180840182612e0a565b949350505050565b5f60208284031215612fd5575f80fd5b81356001600160401b03811115612fea575f80fd5b612fbd84828501612c04565b64ffffffffff848116825260608201906130136020840186612d99565b808416604084015250949350505050565b60208101610fe58284612dad565b5f805f60608486031215613044575f80fd5b833561304f81612b5e565b9250602084013561305f81612b5e565b929592945050506040919091013590565b5f8060208385031215613081575f80fd5b82356001600160401b03811115613096575f80fd5b6130a285828601612caa565b90969095509350505050565b5f602082840312156130be575f80fd5b8135612d7e81612b5e565b5f80602083850312156130da575f80fd5b82356001600160401b03808211156130f0575f80fd5b818501915085601f830112613103575f80fd5b813581811115613111575f80fd5b8660208260051b8501011115613125575f80fd5b60209290920196919550909350505050565b5f8060408385031215613148575f80fd5b823561315381612b5e565b946020939093013593505050565b60038110610ffc575f80fd5b5f6020828403121561317d575f80fd5b8135612d7e81613161565b602081525f612d7e6020830184612ddf565b5f805f606084860312156131ac575f80fd5b83516131b781612d51565b60208501519093506131c881613161565b60408501519092506131d981612d51565b809150509250925092565b604081525f6131f66040830185612ddf565b82810360208401526132088185612ddf565b95945050505050565b5f8183036060811215613222575f80fd5b61322a612b86565b833561323581613161565b81526040601f1983011215613248575f80fd5b613250612b86565b9150602084013561326081612b5e565b8252604084013561327081612d51565b6020838101919091528101919091529392505050565b600181811c9082168061329a57607f821691505b6020821081036132b857634e487b7160e01b5f52602260045260245ffd5b50919050565b634e487b7160e01b5f52601160045260245ffd5b64ffffffffff8181168382160190808211156132f0576132f06132be565b5092915050565b634e487b7160e01b5f52603260045260245ffd5b5f815461331781613286565b808552602060018381168015613334576001811461334e57613379565b60ff1985168884015283151560051b880183019550613379565b865f52825f205f5b858110156133715781548a8201860152908301908401613356565b890184019650505b505050505092915050565b60018060a01b038616815284602082015260a060408201525f6133aa60a083018661330b565b82810360608401526133bc818661330b565b91505082151560808301529695505050505050565b5f602082840312156133e1575f80fd5b81516001600160401b038111156133f6575f80fd5b8201601f81018413613406575f80fd5b8051613414612c2182612bde565b818152856020838501011115613428575f80fd5b613208826020830160208601612dbd565b5f60208284031215613449575f80fd5b5051919050565b5f64ffffffffff808316818103613469576134696132be565b6001019392505050565b5f823560be19833603018112613487575f80fd5b9190910192915050565b8015158114610ffc575f80fd5b600382106134ae576134ae612d85565b805460ff60a81b191660a89290921b60ff60a81b16919091179055565b5f808335601e198436030181126134e0575f80fd5b8301803591506001600160401b038211156134f9575f80fd5b602001915036819003821315612cea575f80fd5b601f82111561076057805f5260205f20601f840160051c810160208510156135325750805b601f840160051c820191505b81811015610926575f815560010161353e565b6001600160401b0383111561356857613568612b72565b61357c836135768354613286565b8361350d565b5f601f8411600181146135ad575f85156135965750838201355b5f19600387901b1c1916600186901b178355610926565b5f83815260208120601f198716915b828110156135dc57868501358255602094850194600190920191016135bc565b50868210156135f8575f1960f88860031b161c19848701351681555b505060018560011b0183555050505050565b813561361581612b5e565b81546001600160a01b031981166001600160a01b03929092169182178355602084013561364181613491565b6001600160a81b03199190911690911790151560a01b60ff60a01b16178155604082013561366e81613161565b613678818361349e565b506060820135600182015561369060808301836134cb565b61369e818360028601613551565b50506136ad60a08301836134cb565b612b58818360038601613551565b5f808335601e198436030181126136d0575f80fd5b83016020810192503590506001600160401b038111156136ee575f80fd5b803603821315612cea575f80fd5b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b60208082528181018390525f906040808401600586901b8501820187855b8881101561381557878303603f190184528135368b900360be19018112613767575f80fd5b8a0160c0813561377681612b5e565b6001600160a01b031685528188013561378e81613491565b151585890152818701356137a181613161565b6137ad88870182612d99565b506060828101359086015260806137c6818401846136bb565b83838901526137d884890182846136fc565b935050505060a06137eb818401846136bb565b9350868303828801526137ff8385836136fc565b978a019796505050928701925050600101613742565b509098975050505050505050565b5f8251613487818460208701612dbd56fea164736f6c6343000816000a
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000058e003a3c6f2aeed6a2a6bc77b504566523cb15c0000000000000000000000009aee0b04504cef83a65ac3f0e838d0593bcb2bc70000000000000000000000000000000000000000000000000000000000000001
-----Decoded View---------------
Arg [0] : crossChainController (address): 0x58e003a3C6f2Aeed6a2a6Bc77B504566523cb15c
Arg [1] : messageOriginator (address): 0x9AEE0B04504CeF83A65AC3f0e838D0593BCb2BC7
Arg [2] : originChainId (uint256): 1
-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 00000000000000000000000058e003a3c6f2aeed6a2a6bc77b504566523cb15c
Arg [1] : 0000000000000000000000009aee0b04504cef83a65ac3f0e838d0593bcb2bc7
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000001
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 31 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
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.