FRAX Price: $1.03 (+6.37%)

Contract

0xf3fD346138C93Cb1c5be1145566e915e54DC5A56

Overview

FRAX Balance | FXTL Balance

0.000000002513835439 FRAX | 223 FXTL

FRAX Value

Less Than $0.01 (@ $1.03/FRAX)

Token Holdings

More Info

Private Name Tags

Multichain Info

No addresses found
Transaction Hash
Block
From
To
Execute311759762026-01-23 10:04:2334 hrs ago1769162663IN
0xf3fD3461...e54DC5A56
0 FRAX0.000016860.00100025
Execute310481412026-01-20 11:03:134 days ago1768906993IN
0xf3fD3461...e54DC5A56
0 FRAX0.000006750.00100025
Execute309834772026-01-18 23:07:455 days ago1768777665IN
0xf3fD3461...e54DC5A56
0 FRAX0.000011510.00100025
Execute309402362026-01-17 23:06:236 days ago1768691183IN
0xf3fD3461...e54DC5A56
0 FRAX0.000008270.00100026
Execute308735512026-01-16 10:03:338 days ago1768557813IN
0xf3fD3461...e54DC5A56
0 FRAX0.000010090.00100025
Execute307460582026-01-13 11:13:4711 days ago1768302827IN
0xf3fD3461...e54DC5A56
0 FRAX0.000006190.00100025
Execute306810582026-01-11 23:07:0712 days ago1768172827IN
0xf3fD3461...e54DC5A56
0 FRAX0.000009430.00100025
Execute306378402026-01-10 23:06:3113 days ago1768086391IN
0xf3fD3461...e54DC5A56
0 FRAX0.000009250.00100025
Execute305711612026-01-09 10:03:5315 days ago1767953033IN
0xf3fD3461...e54DC5A56
0 FRAX0.000009110.00100025
Execute304436912026-01-06 11:14:5318 days ago1767698093IN
0xf3fD3461...e54DC5A56
0 FRAX0.000007460.00100025
Execute303786742026-01-04 23:07:3919 days ago1767568059IN
0xf3fD3461...e54DC5A56
0 FRAX0.000009530.00100025
Execute303354432026-01-03 23:06:3720 days ago1767481597IN
0xf3fD3461...e54DC5A56
0 FRAX0.000007840.00100025
Execute302687452026-01-02 10:03:2122 days ago1767348201IN
0xf3fD3461...e54DC5A56
0 FRAX0.000009710.00100025
Execute301407212025-12-30 10:55:5325 days ago1767092153IN
0xf3fD3461...e54DC5A56
0 FRAX0.000014190.00100025
Execute300762672025-12-28 23:07:2526 days ago1766963245IN
0xf3fD3461...e54DC5A56
0 FRAX0.000010250.00100025
Execute300330432025-12-27 23:06:3727 days ago1766876797IN
0xf3fD3461...e54DC5A56
0 FRAX0.000009630.00100025
Execute299663502025-12-26 10:03:3129 days ago1766743411IN
0xf3fD3461...e54DC5A56
0 FRAX0.000007650.00100025
Execute298373012025-12-23 10:21:5332 days ago1766485313IN
0xf3fD3461...e54DC5A56
0 FRAX0.00000330.00100025
Execute297738482025-12-21 23:06:4733 days ago1766358407IN
0xf3fD3461...e54DC5A56
0 FRAX0.000009540.00100025
Execute297306372025-12-20 23:06:2534 days ago1766271985IN
0xf3fD3461...e54DC5A56
0 FRAX0.00000710.00100025
Execute296639562025-12-19 10:03:4336 days ago1766138623IN
0xf3fD3461...e54DC5A56
0 FRAX0.000007820.00100025
Execute295357832025-12-16 10:51:1739 days ago1765882277IN
0xf3fD3461...e54DC5A56
0 FRAX0.000007990.00100025
Execute294714582025-12-14 23:07:0740 days ago1765753627IN
0xf3fD3461...e54DC5A56
0 FRAX0.000012490.00100025
Execute294282302025-12-13 23:06:1141 days ago1765667171IN
0xf3fD3461...e54DC5A56
0 FRAX0.000009390.00100025
Execute293615612025-12-12 10:03:5343 days ago1765533833IN
0xf3fD3461...e54DC5A56
0 FRAX0.000025820.00100025
View all transactions

Latest 25 internal transactions (View All)

Advanced mode:
Parent Transaction Hash Block From To
311759762026-01-23 10:04:2334 hrs ago1769162663
0xf3fD3461...e54DC5A56
151.27433427 FRAX
311759762026-01-23 10:04:2334 hrs ago1769162663
0xf3fD3461...e54DC5A56
151.27433427 FRAX
308735512026-01-16 10:03:338 days ago1768557813
0xf3fD3461...e54DC5A56
98.03071945 FRAX
308735512026-01-16 10:03:338 days ago1768557813
0xf3fD3461...e54DC5A56
98.03071945 FRAX
305711612026-01-09 10:03:5315 days ago1767953033
0xf3fD3461...e54DC5A56
75.79378209 FRAX
305711612026-01-09 10:03:5315 days ago1767953033
0xf3fD3461...e54DC5A56
75.79378209 FRAX
302687452026-01-02 10:03:2122 days ago1767348201
0xf3fD3461...e54DC5A56
120.28695095 FRAX
302687452026-01-02 10:03:2122 days ago1767348201
0xf3fD3461...e54DC5A56
120.28695095 FRAX
299663502025-12-26 10:03:3129 days ago1766743411
0xf3fD3461...e54DC5A56
76.63506627 FRAX
299663502025-12-26 10:03:3129 days ago1766743411
0xf3fD3461...e54DC5A56
76.63506627 FRAX
296639562025-12-19 10:03:4336 days ago1766138623
0xf3fD3461...e54DC5A56
71.75188553 FRAX
296639562025-12-19 10:03:4336 days ago1766138623
0xf3fD3461...e54DC5A56
71.75188553 FRAX
293615612025-12-12 10:03:5343 days ago1765533833
0xf3fD3461...e54DC5A56
163.24840077 FRAX
293615612025-12-12 10:03:5343 days ago1765533833
0xf3fD3461...e54DC5A56
163.24840077 FRAX
292341832025-12-09 11:17:5746 days ago1765279077
0xf3fD3461...e54DC5A56
123.60855956 FRAX
292341832025-12-09 11:17:5746 days ago1765279077
0xf3fD3461...e54DC5A56
123.60855956 FRAX
289306052025-12-02 10:38:4153 days ago1764671921
0xf3fD3461...e54DC5A56
123.53777408 FRAX
289306052025-12-02 10:38:4153 days ago1764671921
0xf3fD3461...e54DC5A56
123.53777408 FRAX
284543502025-11-21 10:03:3164 days ago1763719411
0xf3fD3461...e54DC5A56
169.32829719 FRAX
284543502025-11-21 10:03:3164 days ago1763719411
0xf3fD3461...e54DC5A56
169.32829719 FRAX
281519592025-11-14 10:03:4971 days ago1763114629
0xf3fD3461...e54DC5A56
131.13305819 FRAX
281519592025-11-14 10:03:4971 days ago1763114629
0xf3fD3461...e54DC5A56
131.13305819 FRAX
278495562025-11-07 10:03:4378 days ago1762509823
0xf3fD3461...e54DC5A56
221.35494824 FRAX
278495562025-11-07 10:03:4378 days ago1762509823
0xf3fD3461...e54DC5A56
221.35494824 FRAX
275471592025-10-31 10:03:4985 days ago1761905029
0xf3fD3461...e54DC5A56
217.27133356 FRAX
View All Internal Transactions

Cross-Chain Transactions
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
AllMight

Compiler Version
v0.8.28+commit.7893614a

Optimization Enabled:
No with 200 runs

Other Settings:
cancun EvmVersion
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity ^0.8.19;

import {VM} from "./weiroll/VM.sol";
import {SafeTransferLib} from "solady/src/utils/SafeTransferLib.sol";

/// @title  AllMight
/// @notice Weiroll implementation that allow to do literally anything.
/// @author Stake DAO
/// @custom:contact [email protected]
contract AllMight is VM {
    using SafeTransferLib for address;

    /// @notice Address of the governance contract.
    address public governance;

    /// @notice Address of the future governance contract.
    address public futureGovernance;

    /// @notice Address authorized to call the execute function.
    mapping(address => bool) public isAllowed;

    ////////////////////////////////////////////////////////////////
    /// --- EVENTS & ERRORS
    ///////////////////////////////////////////////////////////////

    /// @notice Event emitted when a new governance is proposed.
    event GovernanceProposed(address indexed newGovernance);

    /// @notice Event emitted when the governance is changed.
    event GovernanceChanged(address indexed newGovernance);

    /// @notice Event emitted when an address is allowed to execute.
    event AddressAllowed(address indexed allowed);

    /// @notice Event emitted when an address is disallowed from executing.
    event AddressDisallowed(address indexed disallowed);

    /// @notice Event emitted when a weiroll plan is executed.
    event PlanExecuted(address indexed executor, uint256 commandsCount);

    /// @notice Throws if caller is not the governance.
    error GOVERNANCE();

    /// @notice Throws if caller is not allowed.
    error NOT_ALLOWED();

    /// @notice Throws if the length of the tokens and amounts arrays are not equal.
    error WRONG_LENGTH();

    /// @notice Throws if caller is not the contract itself (for self-calls).
    error ONLY_SELF();

    ////////////////////////////////////////////////////////////////
    /// --- MODIFIERS
    ///////////////////////////////////////////////////////////////

    modifier onlyGovernance() {
        if (msg.sender != governance) revert GOVERNANCE();
        _;
    }

    modifier onlyAllowed() {
        if (!isAllowed[msg.sender]) revert NOT_ALLOWED();
        _;
    }

    constructor(address _governance) {
        governance = _governance;
        // Allow governance to execute by default
        isAllowed[_governance] = true;
        emit AddressAllowed(_governance);
    }

    ////////////////////////////////////////////////////////////////
    /// --- ADMIN FUNCTIONS
    ///////////////////////////////////////////////////////////////

    /// @notice Allow an address to call the execute function.
    /// @param _address Address to allow.
    function allowAddress(address _address) external onlyGovernance {
        isAllowed[_address] = true;
        emit AddressAllowed(_address);
    }

    /// @notice Disallow an address to call the execute function.
    /// @param _address Address to disallow.
    function disallowAddress(address _address) external onlyGovernance {
        isAllowed[_address] = false;
        emit AddressDisallowed(_address);
    }

    /// @notice Transfer the governance to a new address.
    /// @param _governance Address of the new governance.
    function transferGovernance(address _governance) external onlyGovernance {
        emit GovernanceProposed(futureGovernance = _governance);
    }

    /// @notice Accept the governance transfer.
    function acceptGovernance() external {
        if (msg.sender != futureGovernance) revert GOVERNANCE();
        emit GovernanceChanged(governance = msg.sender);
    }

    /// @notice Withdraw ETH or ERC20 tokens from the contract.
    function withdraw(address[] calldata _tokens, uint256[] calldata _amount, address _recipient)
        external
        onlyGovernance
    {
        if (_tokens.length != _amount.length) revert WRONG_LENGTH();

        for (uint256 i = 0; i < _tokens.length; i++) {
            if (_tokens[i] == address(0)) {
                SafeTransferLib.safeTransferETH(_recipient, _amount[i]);
            } else {
                SafeTransferLib.safeTransfer(_tokens[i], _recipient, _amount[i]);
            }
        }
    }

    ////////////////////////////////////////////////////////////////
    /// --- EXECUTE FUNCTION
    ///////////////////////////////////////////////////////////////

    /// @notice Execute a list of commands.
    /// @param commands List of commands to execute.
    /// @param state State to execute the commands on.
    function execute(bytes32[] calldata commands, bytes[] memory state)
        external
        payable
        onlyAllowed
        returns (bytes[] memory)
    {
        emit PlanExecuted(msg.sender, commands.length);
        return _execute(commands, state);
    }

    /// @notice Get the ETH balance of this contract.
    /// @return The ETH balance in wei.
    function getBalance() external view returns (uint256) {
        return address(this).balance;
    }

    ////////////////////////////////////////////////////////////////
    /// --- SELF-CALL TRAMPOLINES
    ///////////////////////////////////////////////////////////////

    /// @notice Execute a call with value from within a weiroll plan.
    /// @dev Only callable by the contract itself during plan execution.
    /// @param to Target address to call.
    /// @param value ETH amount to send with the call.
    /// @param data Calldata to send.
    /// @return ret Return data from the call.
    function planCall(address to, uint256 value, bytes calldata data) 
        external 
        returns (bytes memory ret) 
    {
        if (msg.sender != address(this)) revert ONLY_SELF();
        
        (bool success, bytes memory returnData) = to.call{value: value}(data);
        if (!success) {
            // Bubble up the exact revert reason
            assembly { revert(add(returnData, 32), mload(returnData)) }
        }
        return returnData;
    }

    /// @notice Execute a static call from within a weiroll plan.
    /// @dev Only callable by the contract itself during plan execution.
    /// @param to Target address to call.
    /// @param data Calldata to send.
    /// @return ret Return data from the call.
    function planStaticCall(address to, bytes calldata data) 
        external 
        view 
        returns (bytes memory ret) 
    {
        if (msg.sender != address(this)) revert ONLY_SELF();
        
        (bool success, bytes memory returnData) = to.staticcall(data);
        if (!success) {
            // Bubble up the exact revert reason
            assembly { revert(add(returnData, 32), mload(returnData)) }
        }
        return returnData;
    }

    /// @notice Execute a delegatecall from within a weiroll plan.
    /// @dev Only callable by the contract itself during plan execution.
    /// @param to Target address to delegatecall.
    /// @param data Calldata to send.
    /// @return ret Return data from the call.
    function planDelegateCall(address to, bytes calldata data) 
        external 
        returns (bytes memory ret) 
    {
        if (msg.sender != address(this)) revert ONLY_SELF();
        
        (bool success, bytes memory returnData) = to.delegatecall(data);
        if (!success) {
            // Bubble up the exact revert reason
            assembly { revert(add(returnData, 32), mload(returnData)) }
        }
        return returnData;
    }

    receive() external payable {}
}

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.11;

import {CommandBuilder} from "./CommandBuilder.sol";

abstract contract VM {
    using CommandBuilder for bytes[];

    uint256 constant FLAG_CT_DELEGATECALL = 0x00;
    uint256 constant FLAG_CT_CALL = 0x01;
    uint256 constant FLAG_CT_STATICCALL = 0x02;
    uint256 constant FLAG_CT_VALUECALL = 0x03;
    uint256 constant FLAG_CT_MASK = 0x03;
    uint256 constant FLAG_EXTENDED_COMMAND = 0x40;
    uint256 constant FLAG_TUPLE_RETURN = 0x80;

    uint256 constant SHORT_COMMAND_FILL = 0x000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF;

    address immutable self;

    error ExecutionFailed(uint256 command_index, address target, string message);

    constructor() {
        self = address(this);
    }

    function _execute(bytes32[] calldata commands, bytes[] memory state) internal returns (bytes[] memory) {
        bytes32 command;
        uint256 flags;
        bytes32 indices;

        bool success;
        bytes memory outdata;

        uint256 commandsLength = commands.length;
        for (uint256 i; i < commandsLength;) {
            command = commands[i];
            flags = uint256(command >> 216) & 0xFF; // more efficient
            // flags = uint256(uint8(bytes1(command << 32))); // more readable

            if (flags & FLAG_EXTENDED_COMMAND != 0) {
                indices = commands[++i];
            } else {
                indices = bytes32(uint256(command << 40) | SHORT_COMMAND_FILL);
            }

            if (flags & FLAG_CT_MASK == FLAG_CT_DELEGATECALL) {
                (success, outdata) = address(uint160(uint256(command))).delegatecall( // target
                    // inputs
                    state.buildInputs(
                        //selector
                        bytes4(command),
                        indices
                    )
                );
            } else if (flags & FLAG_CT_MASK == FLAG_CT_CALL) {
                (success, outdata) = address(uint160(uint256(command))).call( // target
                    // inputs
                    state.buildInputs(
                        //selector
                        bytes4(command),
                        indices
                    )
                );
            } else if (flags & FLAG_CT_MASK == FLAG_CT_STATICCALL) {
                (success, outdata) = address(uint160(uint256(command))).staticcall( // target
                    // inputs
                    state.buildInputs(
                        //selector
                        bytes4(command),
                        indices
                    )
                );
            } else if (flags & FLAG_CT_MASK == FLAG_CT_VALUECALL) {
                uint256 callEth;
                bytes memory v = state[uint8(bytes1(indices))];
                require(v.length == 32, "_execute: value call has no value indicated.");
                assembly {
                    callEth := mload(add(v, 0x20))
                }
                (success, outdata) = address(uint160(uint256(command))).call{ // target
                    value: callEth
                }(
                    // inputs
                    state.buildInputs(
                        //selector
                        bytes4(command),
                        bytes32(uint256(indices << 8) | CommandBuilder.IDX_END_OF_ARGS)
                    )
                );
            } else {
                revert("Invalid calltype");
            }

            if (!success) {
                if (outdata.length > 0) {
                    assembly {
                        outdata := add(outdata, 68)
                    }
                }
                revert ExecutionFailed({
                    command_index: 0,
                    target: address(uint160(uint256(command))),
                    message: outdata.length > 0 ? string(outdata) : "Unknown"
                });
            }

            if (flags & FLAG_TUPLE_RETURN != 0) {
                state.writeTuple(bytes1(command << 88), outdata);
            } else {
                state = state.writeOutputs(bytes1(command << 88), outdata);
            }
            unchecked {
                ++i;
            }
        }
        return state;
    }
}

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

/// @notice Safe ETH and ERC20 transfer library that gracefully handles missing return values.
/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/SafeTransferLib.sol)
/// @author Modified from Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/SafeTransferLib.sol)
/// @author Permit2 operations from (https://github.com/Uniswap/permit2/blob/main/src/libraries/Permit2Lib.sol)
///
/// @dev Note:
/// - For ETH transfers, please use `forceSafeTransferETH` for DoS protection.
library SafeTransferLib {
    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                       CUSTOM ERRORS                        */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev The ETH transfer has failed.
    error ETHTransferFailed();

    /// @dev The ERC20 `transferFrom` has failed.
    error TransferFromFailed();

    /// @dev The ERC20 `transfer` has failed.
    error TransferFailed();

    /// @dev The ERC20 `approve` has failed.
    error ApproveFailed();

    /// @dev The ERC20 `totalSupply` query has failed.
    error TotalSupplyQueryFailed();

    /// @dev The Permit2 operation has failed.
    error Permit2Failed();

    /// @dev The Permit2 amount must be less than `2**160 - 1`.
    error Permit2AmountOverflow();

    /// @dev The Permit2 approve operation has failed.
    error Permit2ApproveFailed();

    /// @dev The Permit2 lockdown operation has failed.
    error Permit2LockdownFailed();

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                         CONSTANTS                          */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Suggested gas stipend for contract receiving ETH that disallows any storage writes.
    uint256 internal constant GAS_STIPEND_NO_STORAGE_WRITES = 2300;

    /// @dev Suggested gas stipend for contract receiving ETH to perform a few
    /// storage reads and writes, but low enough to prevent griefing.
    uint256 internal constant GAS_STIPEND_NO_GRIEF = 100000;

    /// @dev The unique EIP-712 domain separator for the DAI token contract.
    bytes32 internal constant DAI_DOMAIN_SEPARATOR =
        0xdbb8cf42e1ecb028be3f3dbc922e1d878b963f411dc388ced501601c60f7c6f7;

    /// @dev The address for the WETH9 contract on Ethereum mainnet.
    address internal constant WETH9 = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;

    /// @dev The canonical Permit2 address.
    /// [Github](https://github.com/Uniswap/permit2)
    /// [Etherscan](https://etherscan.io/address/0x000000000022D473030F116dDEE9F6B43aC78BA3)
    address internal constant PERMIT2 = 0x000000000022D473030F116dDEE9F6B43aC78BA3;

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                       ETH OPERATIONS                       */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    // If the ETH transfer MUST succeed with a reasonable gas budget, use the force variants.
    //
    // The regular variants:
    // - Forwards all remaining gas to the target.
    // - Reverts if the target reverts.
    // - Reverts if the current contract has insufficient balance.
    //
    // The force variants:
    // - Forwards with an optional gas stipend
    //   (defaults to `GAS_STIPEND_NO_GRIEF`, which is sufficient for most cases).
    // - If the target reverts, or if the gas stipend is exhausted,
    //   creates a temporary contract to force send the ETH via `SELFDESTRUCT`.
    //   Future compatible with `SENDALL`: https://eips.ethereum.org/EIPS/eip-4758.
    // - Reverts if the current contract has insufficient balance.
    //
    // The try variants:
    // - Forwards with a mandatory gas stipend.
    // - Instead of reverting, returns whether the transfer succeeded.

    /// @dev Sends `amount` (in wei) ETH to `to`.
    function safeTransferETH(address to, uint256 amount) internal {
        /// @solidity memory-safe-assembly
        assembly {
            if iszero(call(gas(), to, amount, codesize(), 0x00, codesize(), 0x00)) {
                mstore(0x00, 0xb12d13eb) // `ETHTransferFailed()`.
                revert(0x1c, 0x04)
            }
        }
    }

    /// @dev Sends all the ETH in the current contract to `to`.
    function safeTransferAllETH(address to) internal {
        /// @solidity memory-safe-assembly
        assembly {
            // Transfer all the ETH and check if it succeeded or not.
            if iszero(call(gas(), to, selfbalance(), codesize(), 0x00, codesize(), 0x00)) {
                mstore(0x00, 0xb12d13eb) // `ETHTransferFailed()`.
                revert(0x1c, 0x04)
            }
        }
    }

    /// @dev Force sends `amount` (in wei) ETH to `to`, with a `gasStipend`.
    function forceSafeTransferETH(address to, uint256 amount, uint256 gasStipend) internal {
        /// @solidity memory-safe-assembly
        assembly {
            if lt(selfbalance(), amount) {
                mstore(0x00, 0xb12d13eb) // `ETHTransferFailed()`.
                revert(0x1c, 0x04)
            }
            if iszero(call(gasStipend, to, amount, codesize(), 0x00, codesize(), 0x00)) {
                mstore(0x00, to) // Store the address in scratch space.
                mstore8(0x0b, 0x73) // Opcode `PUSH20`.
                mstore8(0x20, 0xff) // Opcode `SELFDESTRUCT`.
                if iszero(create(amount, 0x0b, 0x16)) { revert(codesize(), codesize()) } // For gas estimation.
            }
        }
    }

    /// @dev Force sends all the ETH in the current contract to `to`, with a `gasStipend`.
    function forceSafeTransferAllETH(address to, uint256 gasStipend) internal {
        /// @solidity memory-safe-assembly
        assembly {
            if iszero(call(gasStipend, to, selfbalance(), codesize(), 0x00, codesize(), 0x00)) {
                mstore(0x00, to) // Store the address in scratch space.
                mstore8(0x0b, 0x73) // Opcode `PUSH20`.
                mstore8(0x20, 0xff) // Opcode `SELFDESTRUCT`.
                if iszero(create(selfbalance(), 0x0b, 0x16)) { revert(codesize(), codesize()) } // For gas estimation.
            }
        }
    }

    /// @dev Force sends `amount` (in wei) ETH to `to`, with `GAS_STIPEND_NO_GRIEF`.
    function forceSafeTransferETH(address to, uint256 amount) internal {
        /// @solidity memory-safe-assembly
        assembly {
            if lt(selfbalance(), amount) {
                mstore(0x00, 0xb12d13eb) // `ETHTransferFailed()`.
                revert(0x1c, 0x04)
            }
            if iszero(call(GAS_STIPEND_NO_GRIEF, to, amount, codesize(), 0x00, codesize(), 0x00)) {
                mstore(0x00, to) // Store the address in scratch space.
                mstore8(0x0b, 0x73) // Opcode `PUSH20`.
                mstore8(0x20, 0xff) // Opcode `SELFDESTRUCT`.
                if iszero(create(amount, 0x0b, 0x16)) { revert(codesize(), codesize()) } // For gas estimation.
            }
        }
    }

    /// @dev Force sends all the ETH in the current contract to `to`, with `GAS_STIPEND_NO_GRIEF`.
    function forceSafeTransferAllETH(address to) internal {
        /// @solidity memory-safe-assembly
        assembly {
            // forgefmt: disable-next-item
            if iszero(call(GAS_STIPEND_NO_GRIEF, to, selfbalance(), codesize(), 0x00, codesize(), 0x00)) {
                mstore(0x00, to) // Store the address in scratch space.
                mstore8(0x0b, 0x73) // Opcode `PUSH20`.
                mstore8(0x20, 0xff) // Opcode `SELFDESTRUCT`.
                if iszero(create(selfbalance(), 0x0b, 0x16)) { revert(codesize(), codesize()) } // For gas estimation.
            }
        }
    }

    /// @dev Sends `amount` (in wei) ETH to `to`, with a `gasStipend`.
    function trySafeTransferETH(address to, uint256 amount, uint256 gasStipend)
        internal
        returns (bool success)
    {
        /// @solidity memory-safe-assembly
        assembly {
            success := call(gasStipend, to, amount, codesize(), 0x00, codesize(), 0x00)
        }
    }

    /// @dev Sends all the ETH in the current contract to `to`, with a `gasStipend`.
    function trySafeTransferAllETH(address to, uint256 gasStipend)
        internal
        returns (bool success)
    {
        /// @solidity memory-safe-assembly
        assembly {
            success := call(gasStipend, to, selfbalance(), codesize(), 0x00, codesize(), 0x00)
        }
    }

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                      ERC20 OPERATIONS                      */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Sends `amount` of ERC20 `token` from `from` to `to`.
    /// Reverts upon failure.
    ///
    /// The `from` account must have at least `amount` approved for
    /// the current contract to manage.
    function safeTransferFrom(address token, address from, address to, uint256 amount) internal {
        /// @solidity memory-safe-assembly
        assembly {
            let m := mload(0x40) // Cache the free memory pointer.
            mstore(0x60, amount) // Store the `amount` argument.
            mstore(0x40, to) // Store the `to` argument.
            mstore(0x2c, shl(96, from)) // Store the `from` argument.
            mstore(0x0c, 0x23b872dd000000000000000000000000) // `transferFrom(address,address,uint256)`.
            let success := call(gas(), token, 0, 0x1c, 0x64, 0x00, 0x20)
            if iszero(and(eq(mload(0x00), 1), success)) {
                if iszero(lt(or(iszero(extcodesize(token)), returndatasize()), success)) {
                    mstore(0x00, 0x7939f424) // `TransferFromFailed()`.
                    revert(0x1c, 0x04)
                }
            }
            mstore(0x60, 0) // Restore the zero slot to zero.
            mstore(0x40, m) // Restore the free memory pointer.
        }
    }

    /// @dev Sends `amount` of ERC20 `token` from `from` to `to`.
    ///
    /// The `from` account must have at least `amount` approved for the current contract to manage.
    function trySafeTransferFrom(address token, address from, address to, uint256 amount)
        internal
        returns (bool success)
    {
        /// @solidity memory-safe-assembly
        assembly {
            let m := mload(0x40) // Cache the free memory pointer.
            mstore(0x60, amount) // Store the `amount` argument.
            mstore(0x40, to) // Store the `to` argument.
            mstore(0x2c, shl(96, from)) // Store the `from` argument.
            mstore(0x0c, 0x23b872dd000000000000000000000000) // `transferFrom(address,address,uint256)`.
            success := call(gas(), token, 0, 0x1c, 0x64, 0x00, 0x20)
            if iszero(and(eq(mload(0x00), 1), success)) {
                success := lt(or(iszero(extcodesize(token)), returndatasize()), success)
            }
            mstore(0x60, 0) // Restore the zero slot to zero.
            mstore(0x40, m) // Restore the free memory pointer.
        }
    }

    /// @dev Sends all of ERC20 `token` from `from` to `to`.
    /// Reverts upon failure.
    ///
    /// The `from` account must have their entire balance approved for the current contract to manage.
    function safeTransferAllFrom(address token, address from, address to)
        internal
        returns (uint256 amount)
    {
        /// @solidity memory-safe-assembly
        assembly {
            let m := mload(0x40) // Cache the free memory pointer.
            mstore(0x40, to) // Store the `to` argument.
            mstore(0x2c, shl(96, from)) // Store the `from` argument.
            mstore(0x0c, 0x70a08231000000000000000000000000) // `balanceOf(address)`.
            // Read the balance, reverting upon failure.
            if iszero(
                and( // The arguments of `and` are evaluated from right to left.
                    gt(returndatasize(), 0x1f), // At least 32 bytes returned.
                    staticcall(gas(), token, 0x1c, 0x24, 0x60, 0x20)
                )
            ) {
                mstore(0x00, 0x7939f424) // `TransferFromFailed()`.
                revert(0x1c, 0x04)
            }
            mstore(0x00, 0x23b872dd) // `transferFrom(address,address,uint256)`.
            amount := mload(0x60) // The `amount` is already at 0x60. We'll need to return it.
            // Perform the transfer, reverting upon failure.
            let success := call(gas(), token, 0, 0x1c, 0x64, 0x00, 0x20)
            if iszero(and(eq(mload(0x00), 1), success)) {
                if iszero(lt(or(iszero(extcodesize(token)), returndatasize()), success)) {
                    mstore(0x00, 0x7939f424) // `TransferFromFailed()`.
                    revert(0x1c, 0x04)
                }
            }
            mstore(0x60, 0) // Restore the zero slot to zero.
            mstore(0x40, m) // Restore the free memory pointer.
        }
    }

    /// @dev Sends `amount` of ERC20 `token` from the current contract to `to`.
    /// Reverts upon failure.
    function safeTransfer(address token, address to, uint256 amount) internal {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x14, to) // Store the `to` argument.
            mstore(0x34, amount) // Store the `amount` argument.
            mstore(0x00, 0xa9059cbb000000000000000000000000) // `transfer(address,uint256)`.
            // Perform the transfer, reverting upon failure.
            let success := call(gas(), token, 0, 0x10, 0x44, 0x00, 0x20)
            if iszero(and(eq(mload(0x00), 1), success)) {
                if iszero(lt(or(iszero(extcodesize(token)), returndatasize()), success)) {
                    mstore(0x00, 0x90b8ec18) // `TransferFailed()`.
                    revert(0x1c, 0x04)
                }
            }
            mstore(0x34, 0) // Restore the part of the free memory pointer that was overwritten.
        }
    }

    /// @dev Sends all of ERC20 `token` from the current contract to `to`.
    /// Reverts upon failure.
    function safeTransferAll(address token, address to) internal returns (uint256 amount) {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x00, 0x70a08231) // Store the function selector of `balanceOf(address)`.
            mstore(0x20, address()) // Store the address of the current contract.
            // Read the balance, reverting upon failure.
            if iszero(
                and( // The arguments of `and` are evaluated from right to left.
                    gt(returndatasize(), 0x1f), // At least 32 bytes returned.
                    staticcall(gas(), token, 0x1c, 0x24, 0x34, 0x20)
                )
            ) {
                mstore(0x00, 0x90b8ec18) // `TransferFailed()`.
                revert(0x1c, 0x04)
            }
            mstore(0x14, to) // Store the `to` argument.
            amount := mload(0x34) // The `amount` is already at 0x34. We'll need to return it.
            mstore(0x00, 0xa9059cbb000000000000000000000000) // `transfer(address,uint256)`.
            // Perform the transfer, reverting upon failure.
            let success := call(gas(), token, 0, 0x10, 0x44, 0x00, 0x20)
            if iszero(and(eq(mload(0x00), 1), success)) {
                if iszero(lt(or(iszero(extcodesize(token)), returndatasize()), success)) {
                    mstore(0x00, 0x90b8ec18) // `TransferFailed()`.
                    revert(0x1c, 0x04)
                }
            }
            mstore(0x34, 0) // Restore the part of the free memory pointer that was overwritten.
        }
    }

    /// @dev Sets `amount` of ERC20 `token` for `to` to manage on behalf of the current contract.
    /// Reverts upon failure.
    function safeApprove(address token, address to, uint256 amount) internal {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x14, to) // Store the `to` argument.
            mstore(0x34, amount) // Store the `amount` argument.
            mstore(0x00, 0x095ea7b3000000000000000000000000) // `approve(address,uint256)`.
            let success := call(gas(), token, 0, 0x10, 0x44, 0x00, 0x20)
            if iszero(and(eq(mload(0x00), 1), success)) {
                if iszero(lt(or(iszero(extcodesize(token)), returndatasize()), success)) {
                    mstore(0x00, 0x3e3f8f73) // `ApproveFailed()`.
                    revert(0x1c, 0x04)
                }
            }
            mstore(0x34, 0) // Restore the part of the free memory pointer that was overwritten.
        }
    }

    /// @dev Sets `amount` of ERC20 `token` for `to` to manage on behalf of the current contract.
    /// If the initial attempt to approve fails, attempts to reset the approved amount to zero,
    /// then retries the approval again (some tokens, e.g. USDT, requires this).
    /// Reverts upon failure.
    function safeApproveWithRetry(address token, address to, uint256 amount) internal {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x14, to) // Store the `to` argument.
            mstore(0x34, amount) // Store the `amount` argument.
            mstore(0x00, 0x095ea7b3000000000000000000000000) // `approve(address,uint256)`.
            // Perform the approval, retrying upon failure.
            let success := call(gas(), token, 0, 0x10, 0x44, 0x00, 0x20)
            if iszero(and(eq(mload(0x00), 1), success)) {
                if iszero(lt(or(iszero(extcodesize(token)), returndatasize()), success)) {
                    mstore(0x34, 0) // Store 0 for the `amount`.
                    mstore(0x00, 0x095ea7b3000000000000000000000000) // `approve(address,uint256)`.
                    pop(call(gas(), token, 0, 0x10, 0x44, codesize(), 0x00)) // Reset the approval.
                    mstore(0x34, amount) // Store back the original `amount`.
                    // Retry the approval, reverting upon failure.
                    success := call(gas(), token, 0, 0x10, 0x44, 0x00, 0x20)
                    if iszero(and(eq(mload(0x00), 1), success)) {
                        // Check the `extcodesize` again just in case the token selfdestructs lol.
                        if iszero(lt(or(iszero(extcodesize(token)), returndatasize()), success)) {
                            mstore(0x00, 0x3e3f8f73) // `ApproveFailed()`.
                            revert(0x1c, 0x04)
                        }
                    }
                }
            }
            mstore(0x34, 0) // Restore the part of the free memory pointer that was overwritten.
        }
    }

    /// @dev Returns the amount of ERC20 `token` owned by `account`.
    /// Returns zero if the `token` does not exist.
    function balanceOf(address token, address account) internal view returns (uint256 amount) {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x14, account) // Store the `account` argument.
            mstore(0x00, 0x70a08231000000000000000000000000) // `balanceOf(address)`.
            amount :=
                mul( // The arguments of `mul` are evaluated from right to left.
                    mload(0x20),
                    and( // The arguments of `and` are evaluated from right to left.
                        gt(returndatasize(), 0x1f), // At least 32 bytes returned.
                        staticcall(gas(), token, 0x10, 0x24, 0x20, 0x20)
                    )
                )
        }
    }

    /// @dev Performs a `token.balanceOf(account)` check.
    /// `implemented` denotes whether the `token` does not implement `balanceOf`.
    /// `amount` is zero if the `token` does not implement `balanceOf`.
    function checkBalanceOf(address token, address account)
        internal
        view
        returns (bool implemented, uint256 amount)
    {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x14, account) // Store the `account` argument.
            mstore(0x00, 0x70a08231000000000000000000000000) // `balanceOf(address)`.
            implemented :=
                and( // The arguments of `and` are evaluated from right to left.
                    gt(returndatasize(), 0x1f), // At least 32 bytes returned.
                    staticcall(gas(), token, 0x10, 0x24, 0x20, 0x20)
                )
            amount := mul(mload(0x20), implemented)
        }
    }

    /// @dev Returns the total supply of the `token`.
    /// Reverts if the token does not exist or does not implement `totalSupply()`.
    function totalSupply(address token) internal view returns (uint256 result) {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x00, 0x18160ddd) // `totalSupply()`.
            if iszero(
                and(gt(returndatasize(), 0x1f), staticcall(gas(), token, 0x1c, 0x04, 0x00, 0x20))
            ) {
                mstore(0x00, 0x54cd9435) // `TotalSupplyQueryFailed()`.
                revert(0x1c, 0x04)
            }
            result := mload(0x00)
        }
    }

    /// @dev Sends `amount` of ERC20 `token` from `from` to `to`.
    /// If the initial attempt fails, try to use Permit2 to transfer the token.
    /// Reverts upon failure.
    ///
    /// The `from` account must have at least `amount` approved for the current contract to manage.
    function safeTransferFrom2(address token, address from, address to, uint256 amount) internal {
        if (!trySafeTransferFrom(token, from, to, amount)) {
            permit2TransferFrom(token, from, to, amount);
        }
    }

    /// @dev Sends `amount` of ERC20 `token` from `from` to `to` via Permit2.
    /// Reverts upon failure.
    function permit2TransferFrom(address token, address from, address to, uint256 amount)
        internal
    {
        /// @solidity memory-safe-assembly
        assembly {
            let m := mload(0x40)
            mstore(add(m, 0x74), shr(96, shl(96, token)))
            mstore(add(m, 0x54), amount)
            mstore(add(m, 0x34), to)
            mstore(add(m, 0x20), shl(96, from))
            // `transferFrom(address,address,uint160,address)`.
            mstore(m, 0x36c78516000000000000000000000000)
            let p := PERMIT2
            let exists := eq(chainid(), 1)
            if iszero(exists) { exists := iszero(iszero(extcodesize(p))) }
            if iszero(
                and(
                    call(gas(), p, 0, add(m, 0x10), 0x84, codesize(), 0x00),
                    lt(iszero(extcodesize(token)), exists) // Token has code and Permit2 exists.
                )
            ) {
                mstore(0x00, 0x7939f4248757f0fd) // `TransferFromFailed()` or `Permit2AmountOverflow()`.
                revert(add(0x18, shl(2, iszero(iszero(shr(160, amount))))), 0x04)
            }
        }
    }

    /// @dev Permit a user to spend a given amount of
    /// another user's tokens via native EIP-2612 permit if possible, falling
    /// back to Permit2 if native permit fails or is not implemented on the token.
    function permit2(
        address token,
        address owner,
        address spender,
        uint256 amount,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) internal {
        bool success;
        /// @solidity memory-safe-assembly
        assembly {
            for {} shl(96, xor(token, WETH9)) {} {
                mstore(0x00, 0x3644e515) // `DOMAIN_SEPARATOR()`.
                if iszero(
                    and( // The arguments of `and` are evaluated from right to left.
                        lt(iszero(mload(0x00)), eq(returndatasize(), 0x20)), // Returns 1 non-zero word.
                        // Gas stipend to limit gas burn for tokens that don't refund gas when
                        // an non-existing function is called. 5K should be enough for a SLOAD.
                        staticcall(5000, token, 0x1c, 0x04, 0x00, 0x20)
                    )
                ) { break }
                // After here, we can be sure that token is a contract.
                let m := mload(0x40)
                mstore(add(m, 0x34), spender)
                mstore(add(m, 0x20), shl(96, owner))
                mstore(add(m, 0x74), deadline)
                if eq(mload(0x00), DAI_DOMAIN_SEPARATOR) {
                    mstore(0x14, owner)
                    mstore(0x00, 0x7ecebe00000000000000000000000000) // `nonces(address)`.
                    mstore(
                        add(m, 0x94),
                        lt(iszero(amount), staticcall(gas(), token, 0x10, 0x24, add(m, 0x54), 0x20))
                    )
                    mstore(m, 0x8fcbaf0c000000000000000000000000) // `IDAIPermit.permit`.
                    // `nonces` is already at `add(m, 0x54)`.
                    // `amount != 0` is already stored at `add(m, 0x94)`.
                    mstore(add(m, 0xb4), and(0xff, v))
                    mstore(add(m, 0xd4), r)
                    mstore(add(m, 0xf4), s)
                    success := call(gas(), token, 0, add(m, 0x10), 0x104, codesize(), 0x00)
                    break
                }
                mstore(m, 0xd505accf000000000000000000000000) // `IERC20Permit.permit`.
                mstore(add(m, 0x54), amount)
                mstore(add(m, 0x94), and(0xff, v))
                mstore(add(m, 0xb4), r)
                mstore(add(m, 0xd4), s)
                success := call(gas(), token, 0, add(m, 0x10), 0xe4, codesize(), 0x00)
                break
            }
        }
        if (!success) simplePermit2(token, owner, spender, amount, deadline, v, r, s);
    }

    /// @dev Simple permit on the Permit2 contract.
    function simplePermit2(
        address token,
        address owner,
        address spender,
        uint256 amount,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) internal {
        /// @solidity memory-safe-assembly
        assembly {
            let m := mload(0x40)
            mstore(m, 0x927da105) // `allowance(address,address,address)`.
            {
                let addressMask := shr(96, not(0))
                mstore(add(m, 0x20), and(addressMask, owner))
                mstore(add(m, 0x40), and(addressMask, token))
                mstore(add(m, 0x60), and(addressMask, spender))
                mstore(add(m, 0xc0), and(addressMask, spender))
            }
            let p := mul(PERMIT2, iszero(shr(160, amount)))
            if iszero(
                and( // The arguments of `and` are evaluated from right to left.
                    gt(returndatasize(), 0x5f), // Returns 3 words: `amount`, `expiration`, `nonce`.
                    staticcall(gas(), p, add(m, 0x1c), 0x64, add(m, 0x60), 0x60)
                )
            ) {
                mstore(0x00, 0x6b836e6b8757f0fd) // `Permit2Failed()` or `Permit2AmountOverflow()`.
                revert(add(0x18, shl(2, iszero(p))), 0x04)
            }
            mstore(m, 0x2b67b570) // `Permit2.permit` (PermitSingle variant).
            // `owner` is already `add(m, 0x20)`.
            // `token` is already at `add(m, 0x40)`.
            mstore(add(m, 0x60), amount)
            mstore(add(m, 0x80), 0xffffffffffff) // `expiration = type(uint48).max`.
            // `nonce` is already at `add(m, 0xa0)`.
            // `spender` is already at `add(m, 0xc0)`.
            mstore(add(m, 0xe0), deadline)
            mstore(add(m, 0x100), 0x100) // `signature` offset.
            mstore(add(m, 0x120), 0x41) // `signature` length.
            mstore(add(m, 0x140), r)
            mstore(add(m, 0x160), s)
            mstore(add(m, 0x180), shl(248, v))
            if iszero( // Revert if token does not have code, or if the call fails.
            mul(extcodesize(token), call(gas(), p, 0, add(m, 0x1c), 0x184, codesize(), 0x00))) {
                mstore(0x00, 0x6b836e6b) // `Permit2Failed()`.
                revert(0x1c, 0x04)
            }
        }
    }

    /// @dev Approves `spender` to spend `amount` of `token` for `address(this)`.
    function permit2Approve(address token, address spender, uint160 amount, uint48 expiration)
        internal
    {
        /// @solidity memory-safe-assembly
        assembly {
            let addressMask := shr(96, not(0))
            let m := mload(0x40)
            mstore(m, 0x87517c45) // `approve(address,address,uint160,uint48)`.
            mstore(add(m, 0x20), and(addressMask, token))
            mstore(add(m, 0x40), and(addressMask, spender))
            mstore(add(m, 0x60), and(addressMask, amount))
            mstore(add(m, 0x80), and(0xffffffffffff, expiration))
            if iszero(call(gas(), PERMIT2, 0, add(m, 0x1c), 0xa0, codesize(), 0x00)) {
                mstore(0x00, 0x324f14ae) // `Permit2ApproveFailed()`.
                revert(0x1c, 0x04)
            }
        }
    }

    /// @dev Revokes an approval for `token` and `spender` for `address(this)`.
    function permit2Lockdown(address token, address spender) internal {
        /// @solidity memory-safe-assembly
        assembly {
            let m := mload(0x40)
            mstore(m, 0xcc53287f) // `Permit2.lockdown`.
            mstore(add(m, 0x20), 0x20) // Offset of the `approvals`.
            mstore(add(m, 0x40), 1) // `approvals.length`.
            mstore(add(m, 0x60), shr(96, shl(96, token)))
            mstore(add(m, 0x80), shr(96, shl(96, spender)))
            if iszero(call(gas(), PERMIT2, 0, add(m, 0x1c), 0xa0, codesize(), 0x00)) {
                mstore(0x00, 0x96b3de23) // `Permit2LockdownFailed()`.
                revert(0x1c, 0x04)
            }
        }
    }
}

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.11;

library CommandBuilder {
    uint256 constant IDX_VARIABLE_LENGTH = 0x80;
    uint256 constant IDX_VALUE_MASK = 0x7f;
    uint256 constant IDX_END_OF_ARGS = 0xff;
    uint256 constant IDX_USE_STATE = 0xfe;

    function buildInputs(bytes[] memory state, bytes4 selector, bytes32 indices)
        internal
        view
        returns (bytes memory ret)
    {
        uint256 free; // Pointer to first free byte in tail part of message
        uint256 idx;

        // Determine the length of the encoded data
        for (uint256 i; i < 32;) {
            idx = uint8(indices[i]);
            if (idx == IDX_END_OF_ARGS) break;
            unchecked {
                free += 32;
            }
            unchecked {
                ++i;
            }
        }

        // Encode it
        uint256 bytesWritten;
        assembly {
            ret := mload(0x40)
            bytesWritten := add(bytesWritten, 4)
            mstore(0x40, add(ret, and(add(add(bytesWritten, 0x20), 0x1f), not(0x1f))))
            mstore(add(ret, 32), selector)
        }
        uint256 count = 0;
        bytes memory stateData; // Optionally encode the current state if the call requires it
        for (uint256 i; i < 32;) {
            idx = uint8(indices[i]);
            if (idx == IDX_END_OF_ARGS) break;

            if (idx & IDX_VARIABLE_LENGTH != 0) {
                if (idx == IDX_USE_STATE) {
                    assembly {
                        bytesWritten := add(bytesWritten, 32)
                        mstore(0x40, add(ret, and(add(add(bytesWritten, 0x20), 0x1f), not(0x1f))))
                        mstore(add(add(ret, 36), count), free)
                    }
                    if (stateData.length == 0) {
                        stateData = abi.encode(state);
                    }
                    assembly {
                        bytesWritten := add(bytesWritten, mload(stateData))
                        mstore(0x40, add(ret, and(add(add(bytesWritten, 0x20), 0x1f), not(0x1f))))
                    }
                    memcpy(stateData, 32, ret, free + 4, stateData.length - 32);
                    free += stateData.length - 32;
                } else {
                    bytes memory stateVar = state[idx & IDX_VALUE_MASK];
                    uint256 arglen = stateVar.length;

                    // Variable length data; put a pointer in the slot and write the data at the end
                    assembly {
                        bytesWritten := add(bytesWritten, 32)
                        mstore(0x40, add(ret, and(add(add(bytesWritten, 0x20), 0x1f), not(0x1f))))
                        mstore(add(add(ret, 36), count), free)
                    }
                    assembly {
                        bytesWritten := add(bytesWritten, arglen)
                        mstore(0x40, add(ret, and(add(add(bytesWritten, 0x20), 0x1f), not(0x1f))))
                    }
                    memcpy(stateVar, 0, ret, free + 4, arglen);
                    free += arglen;
                }
            } else {
                // Fixed length data; write it directly
                bytes memory stateVar = state[idx & IDX_VALUE_MASK];
                assembly {
                    bytesWritten := add(bytesWritten, mload(stateVar))
                    mstore(0x40, add(ret, and(add(add(bytesWritten, 0x20), 0x1f), not(0x1f))))
                    mstore(add(add(ret, 36), count), mload(add(stateVar, 32)))
                }
            }
            unchecked {
                count += 32;
            }
            unchecked {
                ++i;
            }
        }
        assembly {
            mstore(ret, bytesWritten)
        }
    }

    function writeOutputs(bytes[] memory state, bytes1 index, bytes memory output)
        internal
        pure
        returns (bytes[] memory)
    {
        uint256 idx = uint8(index);
        if (idx == IDX_END_OF_ARGS) return state;

        if (idx & IDX_VARIABLE_LENGTH != 0) {
            if (idx == IDX_USE_STATE) {
                state = abi.decode(output, (bytes[]));
            } else {
                // Check the first field is 0x20 (because we have only a single return value)
                uint256 argptr;
                assembly {
                    argptr := mload(add(output, 32))
                }
                require(argptr == 32, "Only one return value permitted (variable)");

                assembly {
                    // Overwrite the first word of the return data with the length - 32
                    mstore(add(output, 32), sub(mload(output), 32))
                    // Insert a pointer to the return data, starting at the second word, into state
                    mstore(add(add(state, 32), mul(and(idx, IDX_VALUE_MASK), 32)), add(output, 32))
                }
            }
        } else {
            // Single word
            require(output.length == 32, "Only one return value permitted (static)");

            state[idx & IDX_VALUE_MASK] = output;
        }

        return state;
    }

    function writeTuple(bytes[] memory state, bytes1 index, bytes memory output) internal view {
        uint256 idx = uint256(uint8(index));
        if (idx == IDX_END_OF_ARGS) return;

        bytes memory entry = state[idx & IDX_VALUE_MASK] = new bytes(output.length + 32);

        memcpy(output, 0, entry, 32, output.length);
        assembly {
            let l := mload(output)
            mstore(add(entry, 32), l)
        }
    }

    function memcpy(bytes memory src, uint256 srcidx, bytes memory dest, uint256 destidx, uint256 len) internal view {
        assembly {
            pop(staticcall(gas(), 4, add(add(src, 32), srcidx), len, add(add(dest, 32), destidx), len))
        }
    }
}

Settings
{
  "remappings": [
    "solady/=node_modules/solady/",
    "solmate/=node_modules/solmate/",
    "forge-std/=node_modules/forge-std/",
    "@address-book/=node_modules/@stake-dao/address-book/",
    "@openzeppelin/contracts/=node_modules/@openzeppelin/contracts/",
    "solidity-examples/=node_modules/@layerzerolabs/solidity-examples/contracts/",
    "murky/=node_modules/murky.git/src/",
    "murky.git/=node_modules/murky.git/"
  ],
  "optimizer": {
    "enabled": false,
    "runs": 200
  },
  "metadata": {
    "useLiteralContent": false,
    "bytecodeHash": "ipfs",
    "appendCBOR": true
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "evmVersion": "cancun",
  "viaIR": false
}

Contract Security Audit

Contract ABI

API
[{"inputs":[{"internalType":"address","name":"_governance","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"uint256","name":"command_index","type":"uint256"},{"internalType":"address","name":"target","type":"address"},{"internalType":"string","name":"message","type":"string"}],"name":"ExecutionFailed","type":"error"},{"inputs":[],"name":"GOVERNANCE","type":"error"},{"inputs":[],"name":"NOT_ALLOWED","type":"error"},{"inputs":[],"name":"ONLY_SELF","type":"error"},{"inputs":[],"name":"WRONG_LENGTH","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"allowed","type":"address"}],"name":"AddressAllowed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"disallowed","type":"address"}],"name":"AddressDisallowed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newGovernance","type":"address"}],"name":"GovernanceChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newGovernance","type":"address"}],"name":"GovernanceProposed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"executor","type":"address"},{"indexed":false,"internalType":"uint256","name":"commandsCount","type":"uint256"}],"name":"PlanExecuted","type":"event"},{"inputs":[],"name":"acceptGovernance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"allowAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"disallowAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"commands","type":"bytes32[]"},{"internalType":"bytes[]","name":"state","type":"bytes[]"}],"name":"execute","outputs":[{"internalType":"bytes[]","name":"","type":"bytes[]"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"futureGovernance","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"governance","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isAllowed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"planCall","outputs":[{"internalType":"bytes","name":"ret","type":"bytes"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"planDelegateCall","outputs":[{"internalType":"bytes","name":"ret","type":"bytes"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"planStaticCall","outputs":[{"internalType":"bytes","name":"ret","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_governance","type":"address"}],"name":"transferGovernance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_tokens","type":"address[]"},{"internalType":"uint256[]","name":"_amount","type":"uint256[]"},{"internalType":"address","name":"_recipient","type":"address"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]

60a060405234801561000f575f5ffd5b506040516126c53803806126c5833981810160405281019061003191906101a0565b3073ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff1681525050805f5f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600160025f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055508073ffffffffffffffffffffffffffffffffffffffff167f5d20d7597e8195aa92d4ad63482761cfbbe7c4afdef190f27182702924c9af7760405160405180910390a2506101cb565b5f5ffd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f61016f82610146565b9050919050565b61017f81610165565b8114610189575f5ffd5b50565b5f8151905061019a81610176565b92915050565b5f602082840312156101b5576101b4610142565b5b5f6101c28482850161018c565b91505092915050565b6080516124e56101e05f395f50506124e55ff3fe6080604052600436106100c5575f3560e01c80638070c5031161007e578063babcc53911610058578063babcc53914610254578063d38bfff414610290578063de792d5f146102b8578063ebe28064146102e8576100cc565b80638070c503146101c6578063a758d888146101f0578063b7c58d7a1461022c576100cc565b806308af4d88146100d057806312065fe0146100f8578063238efcbc1461012257806326f91506146101385780635aa6e675146101605780637d3902e41461018a576100cc565b366100cc57005b5f5ffd5b3480156100db575f5ffd5b506100f660048036038101906100f19190611700565b610324565b005b348015610103575f5ffd5b5061010c610444565b6040516101199190611743565b60405180910390f35b34801561012d575f5ffd5b5061013661044b565b005b348015610143575f5ffd5b5061015e60048036038101906101599190611812565b610553565b005b34801561016b575f5ffd5b5061017461070a565b60405161018191906118b2565b60405180910390f35b348015610195575f5ffd5b506101b060048036038101906101ab919061194a565b61072e565b6040516101bd9190611a2b565b60405180910390f35b3480156101d1575f5ffd5b506101da61081d565b6040516101e791906118b2565b60405180910390f35b3480156101fb575f5ffd5b5061021660048036038101906102119190611a4b565b610842565b6040516102239190611a2b565b60405180910390f35b348015610237575f5ffd5b50610252600480360381019061024d9190611700565b61092d565b005b34801561025f575f5ffd5b5061027a60048036038101906102759190611700565b610a4c565b6040516102879190611ac2565b60405180910390f35b34801561029b575f5ffd5b506102b660048036038101906102b19190611700565b610a69565b005b6102d260048036038101906102cd9190611d36565b610b72565b6040516102df9190611eb2565b60405180910390f35b3480156102f3575f5ffd5b5061030e60048036038101906103099190611a4b565b610c59565b60405161031b9190611a2b565b60405180910390f35b5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146103a9576040517f1462783400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600160025f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055508073ffffffffffffffffffffffffffffffffffffffff167f5d20d7597e8195aa92d4ad63482761cfbbe7c4afdef190f27182702924c9af7760405160405180910390a250565b5f47905090565b60015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146104d1576040517f1462783400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b335f5f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905573ffffffffffffffffffffffffffffffffffffffff167fa6a85f15b976d399f39ad43e515e75910bac714bc55eeff6131fb90780d6f74660405160405180910390a2565b5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146105d8576040517f1462783400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b828290508585905014610617576040517f5547877e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f5f90505b85859050811015610702575f73ffffffffffffffffffffffffffffffffffffffff1686868381811061065157610650611ed2565b5b90506020020160208101906106669190611700565b73ffffffffffffffffffffffffffffffffffffffff16036106a9576106a48285858481811061069857610697611ed2565b5b90506020020135610d44565b6106f5565b6106f48686838181106106bf576106be611ed2565b5b90506020020160208101906106d49190611700565b838686858181106106e8576106e7611ed2565b5b90506020020135610d61565b5b808060010191505061061c565b505050505050565b5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60603073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610795576040517f46ac008500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f5f8673ffffffffffffffffffffffffffffffffffffffff168686866040516107bf929190611f2d565b5f6040518083038185875af1925050503d805f81146107f9576040519150601f19603f3d011682016040523d82523d5f602084013e6107fe565b606091505b50915091508161081057805160208201fd5b8092505050949350505050565b60015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60603073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146108a9576040517f46ac008500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f5f8573ffffffffffffffffffffffffffffffffffffffff1685856040516108d2929190611f2d565b5f60405180830381855afa9150503d805f811461090a576040519150601f19603f3d011682016040523d82523d5f602084013e61090f565b606091505b50915091508161092157805160208201fd5b80925050509392505050565b5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146109b2576040517f1462783400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f60025f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055508073ffffffffffffffffffffffffffffffffffffffff167f5f1b0fa787087c297cc2ee3a7641860058ab750c330ac3ea5d6d5b9b777f353d60405160405180910390a250565b6002602052805f5260405f205f915054906101000a900460ff1681565b5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610aee576040517f1462783400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8060015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905573ffffffffffffffffffffffffffffffffffffffff167f1f95fb40be3a947982072902a887b521248d1d8931a39eb38f84f4d6fd758b6960405160405180910390a250565b606060025f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16610bf4576040517f95c31a5600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff167fec6bc47979499e97e26dec48279a98e2d73290e0ace85381c5714426c6c1166185859050604051610c3d9190611743565b60405180910390a2610c50848484610db5565b90509392505050565b60603073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610cc0576040517f46ac008500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f5f8573ffffffffffffffffffffffffffffffffffffffff168585604051610ce9929190611f2d565b5f60405180830381855af49150503d805f8114610d21576040519150601f19603f3d011682016040523d82523d5f602084013e610d26565b606091505b509150915081610d3857805160208201fd5b80925050509392505050565b5f385f3884865af1610d5d5763b12d13eb5f526004601cfd5b5050565b81601452806034526fa9059cbb0000000000000000000000005f5260205f604460105f875af18060015f511416610dab57803d853b151710610daa576390b8ec185f526004601cfd5b5b5f60345250505050565b60605f5f5f5f60605f8989905090505f5b81811015611241578a8a82818110610de157610de0611ed2565b5b90506020020135965060ff60d888901c5f1c1695505f6040871614610e2d578a8a82610e0c90611f72565b925082818110610e1f57610e1e611ed2565b5b905060200201359450610e55565b79ffffffffffffffffffffffffffffffffffffffffffffffffffff602888901b5f1c175f1b94505b5f6003871603610ee557865f1c73ffffffffffffffffffffffffffffffffffffffff16610e8d88878c6112529092919063ffffffff16565b604051610e9a9190611fe9565b5f60405180830381855af49150503d805f8114610ed2576040519150601f19603f3d011682016040523d82523d5f602084013e610ed7565b606091505b508094508195505050611156565b60016003871603610f7757865f1c73ffffffffffffffffffffffffffffffffffffffff16610f1e88878c6112529092919063ffffffff16565b604051610f2b9190611fe9565b5f604051808303815f865af19150503d805f8114610f64576040519150601f19603f3d011682016040523d82523d5f602084013e610f69565b606091505b508094508195505050611155565b6002600387160361100857865f1c73ffffffffffffffffffffffffffffffffffffffff16610fb088878c6112529092919063ffffffff16565b604051610fbd9190611fe9565b5f60405180830381855afa9150503d805f8114610ff5576040519150601f19603f3d011682016040523d82523d5f602084013e610ffa565b606091505b508094508195505050611154565b600380871603611118575f5f8a8760f81c60ff168151811061102d5761102c611ed2565b5b60200260200101519050602081511461107b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110729061207f565b60405180910390fd5b60208101519150885f1c73ffffffffffffffffffffffffffffffffffffffff16826110bc8b60ff60088c901b5f1c175f1b8f6112529092919063ffffffff16565b6040516110c99190611fe9565b5f6040518083038185875af1925050503d805f8114611103576040519150601f19603f3d011682016040523d82523d5f602084013e611108565b606091505b5080965081975050505050611153565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161114a906120e7565b60405180910390fd5b5b5b5b836111f2575f8351111561116b576044830192505b5f875f1c5f8551116111b2576040518060400160405280600781526020017f556e6b6e6f776e000000000000000000000000000000000000000000000000008152506111b4565b845b6040517fef3dcb2f0000000000000000000000000000000000000000000000000000000081526004016111e993929190612189565b60405180910390fd5b5f608087161461121a57611215605888901b848b61149c9092919063ffffffff16565b611236565b611233605888901b848b6115519092919063ffffffff16565b98505b806001019050610dc6565b508796505050505050509392505050565b60605f5f5f5b602081101561129a5784816020811061127457611273611ed2565b5b1a60f81b60f81c60ff16915060ff82031561129a57602083019250806001019050611258565b505f6040519350600481019050601f19601f60208301011684016040528560208501525f5f905060605f5b602081101561148c578781602081106112e1576112e0611ed2565b5b1a60f81b60f81c60ff16945060ff85031561148c575f60808616146114365760fe85036113ae57602084019350601f19601f602086010116870160405285836024890101525f825103611351578960405160200161133f9190611eb2565b60405160208183030381529060405291505b815184019350601f19601f602086010116870160405261138e8260208960048a61137b91906121c5565b6020875161138991906121f8565b61167b565b6020825161139c91906121f8565b866113a791906121c5565b9550611431565b5f8a607f8716815181106113c5576113c4611ed2565b5b602002602001015190505f81519050602086019550601f19601f6020880101168901604052878560248b0101528086019550601f19601f6020880101168901604052611420825f8b60048c61141a91906121c5565b8561167b565b808861142c91906121c5565b975050505b61147b565b5f8a607f87168151811061144d5761144c611ed2565b5b60200260200101519050805185019450601f19601f602087010116880160405260208101518460248a010152505b6020830192508060010190506112c5565b5082865250505050509392505050565b5f8260f81c60ff16905060ff81036114b4575061154c565b5f602083516114c391906121c5565b67ffffffffffffffff8111156114dc576114db611b30565b5b6040519080825280601f01601f19166020018201604052801561150e5781602001600182028036833780820191505090505b5085607f84168151811061152557611524611ed2565b5b602002602001018190529050611540835f836020875161167b565b82518060208301525050505b505050565b60605f8360f81c60ff16905060ff810361156e5784915050611674565b5f60808216146116085760fe810361159b5782806020019051810190611594919061234c565b9450611603565b5f60208401519050602081146115e6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115dd90612403565b60405180910390fd5b60208451036020850152602084016020607f841602602088010152505b61166f565b602083511461164c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161164390612491565b60405180910390fd5b8285607f83168151811061166357611662611ed2565b5b60200260200101819052505b849150505b9392505050565b808260208501018286602089010160045afa505050505050565b5f604051905090565b5f5ffd5b5f5ffd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6116cf826116a6565b9050919050565b6116df816116c5565b81146116e9575f5ffd5b50565b5f813590506116fa816116d6565b92915050565b5f602082840312156117155761171461169e565b5b5f611722848285016116ec565b91505092915050565b5f819050919050565b61173d8161172b565b82525050565b5f6020820190506117565f830184611734565b92915050565b5f5ffd5b5f5ffd5b5f5ffd5b5f5f83601f84011261177d5761177c61175c565b5b8235905067ffffffffffffffff81111561179a57611799611760565b5b6020830191508360208202830111156117b6576117b5611764565b5b9250929050565b5f5f83601f8401126117d2576117d161175c565b5b8235905067ffffffffffffffff8111156117ef576117ee611760565b5b60208301915083602082028301111561180b5761180a611764565b5b9250929050565b5f5f5f5f5f6060868803121561182b5761182a61169e565b5b5f86013567ffffffffffffffff811115611848576118476116a2565b5b61185488828901611768565b9550955050602086013567ffffffffffffffff811115611877576118766116a2565b5b611883888289016117bd565b93509350506040611896888289016116ec565b9150509295509295909350565b6118ac816116c5565b82525050565b5f6020820190506118c55f8301846118a3565b92915050565b6118d48161172b565b81146118de575f5ffd5b50565b5f813590506118ef816118cb565b92915050565b5f5f83601f84011261190a5761190961175c565b5b8235905067ffffffffffffffff81111561192757611926611760565b5b60208301915083600182028301111561194357611942611764565b5b9250929050565b5f5f5f5f606085870312156119625761196161169e565b5b5f61196f878288016116ec565b9450506020611980878288016118e1565b935050604085013567ffffffffffffffff8111156119a1576119a06116a2565b5b6119ad878288016118f5565b925092505092959194509250565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f6119fd826119bb565b611a0781856119c5565b9350611a178185602086016119d5565b611a20816119e3565b840191505092915050565b5f6020820190508181035f830152611a4381846119f3565b905092915050565b5f5f5f60408486031215611a6257611a6161169e565b5b5f611a6f868287016116ec565b935050602084013567ffffffffffffffff811115611a9057611a8f6116a2565b5b611a9c868287016118f5565b92509250509250925092565b5f8115159050919050565b611abc81611aa8565b82525050565b5f602082019050611ad55f830184611ab3565b92915050565b5f5f83601f840112611af057611aef61175c565b5b8235905067ffffffffffffffff811115611b0d57611b0c611760565b5b602083019150836020820283011115611b2957611b28611764565b5b9250929050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b611b66826119e3565b810181811067ffffffffffffffff82111715611b8557611b84611b30565b5b80604052505050565b5f611b97611695565b9050611ba38282611b5d565b919050565b5f67ffffffffffffffff821115611bc257611bc1611b30565b5b602082029050602081019050919050565b5f5ffd5b5f67ffffffffffffffff821115611bf157611bf0611b30565b5b611bfa826119e3565b9050602081019050919050565b828183375f83830152505050565b5f611c27611c2284611bd7565b611b8e565b905082815260208101848484011115611c4357611c42611bd3565b5b611c4e848285611c07565b509392505050565b5f82601f830112611c6a57611c6961175c565b5b8135611c7a848260208601611c15565b91505092915050565b5f611c95611c9084611ba8565b611b8e565b90508083825260208201905060208402830185811115611cb857611cb7611764565b5b835b81811015611cff57803567ffffffffffffffff811115611cdd57611cdc61175c565b5b808601611cea8982611c56565b85526020850194505050602081019050611cba565b5050509392505050565b5f82601f830112611d1d57611d1c61175c565b5b8135611d2d848260208601611c83565b91505092915050565b5f5f5f60408486031215611d4d57611d4c61169e565b5b5f84013567ffffffffffffffff811115611d6a57611d696116a2565b5b611d7686828701611adb565b9350935050602084013567ffffffffffffffff811115611d9957611d986116a2565b5b611da586828701611d09565b9150509250925092565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b5f82825260208201905092915050565b5f611df2826119bb565b611dfc8185611dd8565b9350611e0c8185602086016119d5565b611e15816119e3565b840191505092915050565b5f611e2b8383611de8565b905092915050565b5f602082019050919050565b5f611e4982611daf565b611e538185611db9565b935083602082028501611e6585611dc9565b805f5b85811015611ea05784840389528151611e818582611e20565b9450611e8c83611e33565b925060208a01995050600181019050611e68565b50829750879550505050505092915050565b5f6020820190508181035f830152611eca8184611e3f565b905092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f81905092915050565b5f611f148385611eff565b9350611f21838584611c07565b82840190509392505050565b5f611f39828486611f09565b91508190509392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f611f7c8261172b565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611fae57611fad611f45565b5b600182019050919050565b5f611fc3826119bb565b611fcd8185611eff565b9350611fdd8185602086016119d5565b80840191505092915050565b5f611ff48284611fb9565b915081905092915050565b5f82825260208201905092915050565b7f5f657865637574653a2076616c75652063616c6c20686173206e6f2076616c755f8201527f6520696e646963617465642e0000000000000000000000000000000000000000602082015250565b5f612069602c83611fff565b91506120748261200f565b604082019050919050565b5f6020820190508181035f8301526120968161205d565b9050919050565b7f496e76616c69642063616c6c74797065000000000000000000000000000000005f82015250565b5f6120d1601083611fff565b91506120dc8261209d565b602082019050919050565b5f6020820190508181035f8301526120fe816120c5565b9050919050565b5f819050919050565b5f819050919050565b5f61213161212c61212784612105565b61210e565b61172b565b9050919050565b61214181612117565b82525050565b5f81519050919050565b5f61215b82612147565b6121658185611fff565b93506121758185602086016119d5565b61217e816119e3565b840191505092915050565b5f60608201905061219c5f830186612138565b6121a960208301856118a3565b81810360408301526121bb8184612151565b9050949350505050565b5f6121cf8261172b565b91506121da8361172b565b92508282019050808211156121f2576121f1611f45565b5b92915050565b5f6122028261172b565b915061220d8361172b565b925082820390508181111561222557612224611f45565b5b92915050565b5f61223d61223884611bd7565b611b8e565b90508281526020810184848401111561225957612258611bd3565b5b6122648482856119d5565b509392505050565b5f82601f8301126122805761227f61175c565b5b815161229084826020860161222b565b91505092915050565b5f6122ab6122a684611ba8565b611b8e565b905080838252602082019050602084028301858111156122ce576122cd611764565b5b835b8181101561231557805167ffffffffffffffff8111156122f3576122f261175c565b5b808601612300898261226c565b855260208501945050506020810190506122d0565b5050509392505050565b5f82601f8301126123335761233261175c565b5b8151612343848260208601612299565b91505092915050565b5f602082840312156123615761236061169e565b5b5f82015167ffffffffffffffff81111561237e5761237d6116a2565b5b61238a8482850161231f565b91505092915050565b7f4f6e6c79206f6e652072657475726e2076616c7565207065726d6974746564205f8201527f287661726961626c652900000000000000000000000000000000000000000000602082015250565b5f6123ed602a83611fff565b91506123f882612393565b604082019050919050565b5f6020820190508181035f83015261241a816123e1565b9050919050565b7f4f6e6c79206f6e652072657475726e2076616c7565207065726d6974746564205f8201527f2873746174696329000000000000000000000000000000000000000000000000602082015250565b5f61247b602883611fff565b915061248682612421565b604082019050919050565b5f6020820190508181035f8301526124a88161246f565b905091905056fea2646970667358221220839a25e760d41efb0297bbd715e5c60aafeb08ea788fb4a9db75365d6050c2e264736f6c634300081c00330000000000000000000000008898502ba35ab64b3562abc509befb7eb178d4df

Deployed Bytecode

0x6080604052600436106100c5575f3560e01c80638070c5031161007e578063babcc53911610058578063babcc53914610254578063d38bfff414610290578063de792d5f146102b8578063ebe28064146102e8576100cc565b80638070c503146101c6578063a758d888146101f0578063b7c58d7a1461022c576100cc565b806308af4d88146100d057806312065fe0146100f8578063238efcbc1461012257806326f91506146101385780635aa6e675146101605780637d3902e41461018a576100cc565b366100cc57005b5f5ffd5b3480156100db575f5ffd5b506100f660048036038101906100f19190611700565b610324565b005b348015610103575f5ffd5b5061010c610444565b6040516101199190611743565b60405180910390f35b34801561012d575f5ffd5b5061013661044b565b005b348015610143575f5ffd5b5061015e60048036038101906101599190611812565b610553565b005b34801561016b575f5ffd5b5061017461070a565b60405161018191906118b2565b60405180910390f35b348015610195575f5ffd5b506101b060048036038101906101ab919061194a565b61072e565b6040516101bd9190611a2b565b60405180910390f35b3480156101d1575f5ffd5b506101da61081d565b6040516101e791906118b2565b60405180910390f35b3480156101fb575f5ffd5b5061021660048036038101906102119190611a4b565b610842565b6040516102239190611a2b565b60405180910390f35b348015610237575f5ffd5b50610252600480360381019061024d9190611700565b61092d565b005b34801561025f575f5ffd5b5061027a60048036038101906102759190611700565b610a4c565b6040516102879190611ac2565b60405180910390f35b34801561029b575f5ffd5b506102b660048036038101906102b19190611700565b610a69565b005b6102d260048036038101906102cd9190611d36565b610b72565b6040516102df9190611eb2565b60405180910390f35b3480156102f3575f5ffd5b5061030e60048036038101906103099190611a4b565b610c59565b60405161031b9190611a2b565b60405180910390f35b5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146103a9576040517f1462783400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600160025f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055508073ffffffffffffffffffffffffffffffffffffffff167f5d20d7597e8195aa92d4ad63482761cfbbe7c4afdef190f27182702924c9af7760405160405180910390a250565b5f47905090565b60015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146104d1576040517f1462783400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b335f5f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905573ffffffffffffffffffffffffffffffffffffffff167fa6a85f15b976d399f39ad43e515e75910bac714bc55eeff6131fb90780d6f74660405160405180910390a2565b5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146105d8576040517f1462783400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b828290508585905014610617576040517f5547877e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f5f90505b85859050811015610702575f73ffffffffffffffffffffffffffffffffffffffff1686868381811061065157610650611ed2565b5b90506020020160208101906106669190611700565b73ffffffffffffffffffffffffffffffffffffffff16036106a9576106a48285858481811061069857610697611ed2565b5b90506020020135610d44565b6106f5565b6106f48686838181106106bf576106be611ed2565b5b90506020020160208101906106d49190611700565b838686858181106106e8576106e7611ed2565b5b90506020020135610d61565b5b808060010191505061061c565b505050505050565b5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60603073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610795576040517f46ac008500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f5f8673ffffffffffffffffffffffffffffffffffffffff168686866040516107bf929190611f2d565b5f6040518083038185875af1925050503d805f81146107f9576040519150601f19603f3d011682016040523d82523d5f602084013e6107fe565b606091505b50915091508161081057805160208201fd5b8092505050949350505050565b60015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60603073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146108a9576040517f46ac008500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f5f8573ffffffffffffffffffffffffffffffffffffffff1685856040516108d2929190611f2d565b5f60405180830381855afa9150503d805f811461090a576040519150601f19603f3d011682016040523d82523d5f602084013e61090f565b606091505b50915091508161092157805160208201fd5b80925050509392505050565b5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146109b2576040517f1462783400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f60025f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055508073ffffffffffffffffffffffffffffffffffffffff167f5f1b0fa787087c297cc2ee3a7641860058ab750c330ac3ea5d6d5b9b777f353d60405160405180910390a250565b6002602052805f5260405f205f915054906101000a900460ff1681565b5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610aee576040517f1462783400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8060015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905573ffffffffffffffffffffffffffffffffffffffff167f1f95fb40be3a947982072902a887b521248d1d8931a39eb38f84f4d6fd758b6960405160405180910390a250565b606060025f3373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16610bf4576040517f95c31a5600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff167fec6bc47979499e97e26dec48279a98e2d73290e0ace85381c5714426c6c1166185859050604051610c3d9190611743565b60405180910390a2610c50848484610db5565b90509392505050565b60603073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610cc0576040517f46ac008500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f5f8573ffffffffffffffffffffffffffffffffffffffff168585604051610ce9929190611f2d565b5f60405180830381855af49150503d805f8114610d21576040519150601f19603f3d011682016040523d82523d5f602084013e610d26565b606091505b509150915081610d3857805160208201fd5b80925050509392505050565b5f385f3884865af1610d5d5763b12d13eb5f526004601cfd5b5050565b81601452806034526fa9059cbb0000000000000000000000005f5260205f604460105f875af18060015f511416610dab57803d853b151710610daa576390b8ec185f526004601cfd5b5b5f60345250505050565b60605f5f5f5f60605f8989905090505f5b81811015611241578a8a82818110610de157610de0611ed2565b5b90506020020135965060ff60d888901c5f1c1695505f6040871614610e2d578a8a82610e0c90611f72565b925082818110610e1f57610e1e611ed2565b5b905060200201359450610e55565b79ffffffffffffffffffffffffffffffffffffffffffffffffffff602888901b5f1c175f1b94505b5f6003871603610ee557865f1c73ffffffffffffffffffffffffffffffffffffffff16610e8d88878c6112529092919063ffffffff16565b604051610e9a9190611fe9565b5f60405180830381855af49150503d805f8114610ed2576040519150601f19603f3d011682016040523d82523d5f602084013e610ed7565b606091505b508094508195505050611156565b60016003871603610f7757865f1c73ffffffffffffffffffffffffffffffffffffffff16610f1e88878c6112529092919063ffffffff16565b604051610f2b9190611fe9565b5f604051808303815f865af19150503d805f8114610f64576040519150601f19603f3d011682016040523d82523d5f602084013e610f69565b606091505b508094508195505050611155565b6002600387160361100857865f1c73ffffffffffffffffffffffffffffffffffffffff16610fb088878c6112529092919063ffffffff16565b604051610fbd9190611fe9565b5f60405180830381855afa9150503d805f8114610ff5576040519150601f19603f3d011682016040523d82523d5f602084013e610ffa565b606091505b508094508195505050611154565b600380871603611118575f5f8a8760f81c60ff168151811061102d5761102c611ed2565b5b60200260200101519050602081511461107b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110729061207f565b60405180910390fd5b60208101519150885f1c73ffffffffffffffffffffffffffffffffffffffff16826110bc8b60ff60088c901b5f1c175f1b8f6112529092919063ffffffff16565b6040516110c99190611fe9565b5f6040518083038185875af1925050503d805f8114611103576040519150601f19603f3d011682016040523d82523d5f602084013e611108565b606091505b5080965081975050505050611153565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161114a906120e7565b60405180910390fd5b5b5b5b836111f2575f8351111561116b576044830192505b5f875f1c5f8551116111b2576040518060400160405280600781526020017f556e6b6e6f776e000000000000000000000000000000000000000000000000008152506111b4565b845b6040517fef3dcb2f0000000000000000000000000000000000000000000000000000000081526004016111e993929190612189565b60405180910390fd5b5f608087161461121a57611215605888901b848b61149c9092919063ffffffff16565b611236565b611233605888901b848b6115519092919063ffffffff16565b98505b806001019050610dc6565b508796505050505050509392505050565b60605f5f5f5b602081101561129a5784816020811061127457611273611ed2565b5b1a60f81b60f81c60ff16915060ff82031561129a57602083019250806001019050611258565b505f6040519350600481019050601f19601f60208301011684016040528560208501525f5f905060605f5b602081101561148c578781602081106112e1576112e0611ed2565b5b1a60f81b60f81c60ff16945060ff85031561148c575f60808616146114365760fe85036113ae57602084019350601f19601f602086010116870160405285836024890101525f825103611351578960405160200161133f9190611eb2565b60405160208183030381529060405291505b815184019350601f19601f602086010116870160405261138e8260208960048a61137b91906121c5565b6020875161138991906121f8565b61167b565b6020825161139c91906121f8565b866113a791906121c5565b9550611431565b5f8a607f8716815181106113c5576113c4611ed2565b5b602002602001015190505f81519050602086019550601f19601f6020880101168901604052878560248b0101528086019550601f19601f6020880101168901604052611420825f8b60048c61141a91906121c5565b8561167b565b808861142c91906121c5565b975050505b61147b565b5f8a607f87168151811061144d5761144c611ed2565b5b60200260200101519050805185019450601f19601f602087010116880160405260208101518460248a010152505b6020830192508060010190506112c5565b5082865250505050509392505050565b5f8260f81c60ff16905060ff81036114b4575061154c565b5f602083516114c391906121c5565b67ffffffffffffffff8111156114dc576114db611b30565b5b6040519080825280601f01601f19166020018201604052801561150e5781602001600182028036833780820191505090505b5085607f84168151811061152557611524611ed2565b5b602002602001018190529050611540835f836020875161167b565b82518060208301525050505b505050565b60605f8360f81c60ff16905060ff810361156e5784915050611674565b5f60808216146116085760fe810361159b5782806020019051810190611594919061234c565b9450611603565b5f60208401519050602081146115e6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115dd90612403565b60405180910390fd5b60208451036020850152602084016020607f841602602088010152505b61166f565b602083511461164c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161164390612491565b60405180910390fd5b8285607f83168151811061166357611662611ed2565b5b60200260200101819052505b849150505b9392505050565b808260208501018286602089010160045afa505050505050565b5f604051905090565b5f5ffd5b5f5ffd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6116cf826116a6565b9050919050565b6116df816116c5565b81146116e9575f5ffd5b50565b5f813590506116fa816116d6565b92915050565b5f602082840312156117155761171461169e565b5b5f611722848285016116ec565b91505092915050565b5f819050919050565b61173d8161172b565b82525050565b5f6020820190506117565f830184611734565b92915050565b5f5ffd5b5f5ffd5b5f5ffd5b5f5f83601f84011261177d5761177c61175c565b5b8235905067ffffffffffffffff81111561179a57611799611760565b5b6020830191508360208202830111156117b6576117b5611764565b5b9250929050565b5f5f83601f8401126117d2576117d161175c565b5b8235905067ffffffffffffffff8111156117ef576117ee611760565b5b60208301915083602082028301111561180b5761180a611764565b5b9250929050565b5f5f5f5f5f6060868803121561182b5761182a61169e565b5b5f86013567ffffffffffffffff811115611848576118476116a2565b5b61185488828901611768565b9550955050602086013567ffffffffffffffff811115611877576118766116a2565b5b611883888289016117bd565b93509350506040611896888289016116ec565b9150509295509295909350565b6118ac816116c5565b82525050565b5f6020820190506118c55f8301846118a3565b92915050565b6118d48161172b565b81146118de575f5ffd5b50565b5f813590506118ef816118cb565b92915050565b5f5f83601f84011261190a5761190961175c565b5b8235905067ffffffffffffffff81111561192757611926611760565b5b60208301915083600182028301111561194357611942611764565b5b9250929050565b5f5f5f5f606085870312156119625761196161169e565b5b5f61196f878288016116ec565b9450506020611980878288016118e1565b935050604085013567ffffffffffffffff8111156119a1576119a06116a2565b5b6119ad878288016118f5565b925092505092959194509250565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f6119fd826119bb565b611a0781856119c5565b9350611a178185602086016119d5565b611a20816119e3565b840191505092915050565b5f6020820190508181035f830152611a4381846119f3565b905092915050565b5f5f5f60408486031215611a6257611a6161169e565b5b5f611a6f868287016116ec565b935050602084013567ffffffffffffffff811115611a9057611a8f6116a2565b5b611a9c868287016118f5565b92509250509250925092565b5f8115159050919050565b611abc81611aa8565b82525050565b5f602082019050611ad55f830184611ab3565b92915050565b5f5f83601f840112611af057611aef61175c565b5b8235905067ffffffffffffffff811115611b0d57611b0c611760565b5b602083019150836020820283011115611b2957611b28611764565b5b9250929050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b611b66826119e3565b810181811067ffffffffffffffff82111715611b8557611b84611b30565b5b80604052505050565b5f611b97611695565b9050611ba38282611b5d565b919050565b5f67ffffffffffffffff821115611bc257611bc1611b30565b5b602082029050602081019050919050565b5f5ffd5b5f67ffffffffffffffff821115611bf157611bf0611b30565b5b611bfa826119e3565b9050602081019050919050565b828183375f83830152505050565b5f611c27611c2284611bd7565b611b8e565b905082815260208101848484011115611c4357611c42611bd3565b5b611c4e848285611c07565b509392505050565b5f82601f830112611c6a57611c6961175c565b5b8135611c7a848260208601611c15565b91505092915050565b5f611c95611c9084611ba8565b611b8e565b90508083825260208201905060208402830185811115611cb857611cb7611764565b5b835b81811015611cff57803567ffffffffffffffff811115611cdd57611cdc61175c565b5b808601611cea8982611c56565b85526020850194505050602081019050611cba565b5050509392505050565b5f82601f830112611d1d57611d1c61175c565b5b8135611d2d848260208601611c83565b91505092915050565b5f5f5f60408486031215611d4d57611d4c61169e565b5b5f84013567ffffffffffffffff811115611d6a57611d696116a2565b5b611d7686828701611adb565b9350935050602084013567ffffffffffffffff811115611d9957611d986116a2565b5b611da586828701611d09565b9150509250925092565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b5f82825260208201905092915050565b5f611df2826119bb565b611dfc8185611dd8565b9350611e0c8185602086016119d5565b611e15816119e3565b840191505092915050565b5f611e2b8383611de8565b905092915050565b5f602082019050919050565b5f611e4982611daf565b611e538185611db9565b935083602082028501611e6585611dc9565b805f5b85811015611ea05784840389528151611e818582611e20565b9450611e8c83611e33565b925060208a01995050600181019050611e68565b50829750879550505050505092915050565b5f6020820190508181035f830152611eca8184611e3f565b905092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f81905092915050565b5f611f148385611eff565b9350611f21838584611c07565b82840190509392505050565b5f611f39828486611f09565b91508190509392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f611f7c8261172b565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611fae57611fad611f45565b5b600182019050919050565b5f611fc3826119bb565b611fcd8185611eff565b9350611fdd8185602086016119d5565b80840191505092915050565b5f611ff48284611fb9565b915081905092915050565b5f82825260208201905092915050565b7f5f657865637574653a2076616c75652063616c6c20686173206e6f2076616c755f8201527f6520696e646963617465642e0000000000000000000000000000000000000000602082015250565b5f612069602c83611fff565b91506120748261200f565b604082019050919050565b5f6020820190508181035f8301526120968161205d565b9050919050565b7f496e76616c69642063616c6c74797065000000000000000000000000000000005f82015250565b5f6120d1601083611fff565b91506120dc8261209d565b602082019050919050565b5f6020820190508181035f8301526120fe816120c5565b9050919050565b5f819050919050565b5f819050919050565b5f61213161212c61212784612105565b61210e565b61172b565b9050919050565b61214181612117565b82525050565b5f81519050919050565b5f61215b82612147565b6121658185611fff565b93506121758185602086016119d5565b61217e816119e3565b840191505092915050565b5f60608201905061219c5f830186612138565b6121a960208301856118a3565b81810360408301526121bb8184612151565b9050949350505050565b5f6121cf8261172b565b91506121da8361172b565b92508282019050808211156121f2576121f1611f45565b5b92915050565b5f6122028261172b565b915061220d8361172b565b925082820390508181111561222557612224611f45565b5b92915050565b5f61223d61223884611bd7565b611b8e565b90508281526020810184848401111561225957612258611bd3565b5b6122648482856119d5565b509392505050565b5f82601f8301126122805761227f61175c565b5b815161229084826020860161222b565b91505092915050565b5f6122ab6122a684611ba8565b611b8e565b905080838252602082019050602084028301858111156122ce576122cd611764565b5b835b8181101561231557805167ffffffffffffffff8111156122f3576122f261175c565b5b808601612300898261226c565b855260208501945050506020810190506122d0565b5050509392505050565b5f82601f8301126123335761233261175c565b5b8151612343848260208601612299565b91505092915050565b5f602082840312156123615761236061169e565b5b5f82015167ffffffffffffffff81111561237e5761237d6116a2565b5b61238a8482850161231f565b91505092915050565b7f4f6e6c79206f6e652072657475726e2076616c7565207065726d6974746564205f8201527f287661726961626c652900000000000000000000000000000000000000000000602082015250565b5f6123ed602a83611fff565b91506123f882612393565b604082019050919050565b5f6020820190508181035f83015261241a816123e1565b9050919050565b7f4f6e6c79206f6e652072657475726e2076616c7565207065726d6974746564205f8201527f2873746174696329000000000000000000000000000000000000000000000000602082015250565b5f61247b602883611fff565b915061248682612421565b604082019050919050565b5f6020820190508181035f8301526124a88161246f565b905091905056fea2646970667358221220839a25e760d41efb0297bbd715e5c60aafeb08ea788fb4a9db75365d6050c2e264736f6c634300081c0033

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

0000000000000000000000008898502ba35ab64b3562abc509befb7eb178d4df

-----Decoded View---------------
Arg [0] : _governance (address): 0x8898502BA35AB64b3562aBC509Befb7Eb178D4df

-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 0000000000000000000000008898502ba35ab64b3562abc509befb7eb178d4df


Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

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.