ETH Price: $1,593.09 (-3.05%)
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Execute195742502024-04-03 9:07:11375 days ago1712135231IN
0x67D19dcb...A4A146A56
0 ETH0.0017598424.43894142
Execute195742222024-04-03 9:01:23375 days ago1712134883IN
0x67D19dcb...A4A146A56
0 ETH0.003157825.53230269
Execute195742212024-04-03 9:01:11375 days ago1712134871IN
0x67D19dcb...A4A146A56
0 ETH0.0022198123.18608808
Execute195741932024-04-03 8:55:23375 days ago1712134523IN
0x67D19dcb...A4A146A56
0 ETH0.0032009225.67869551
Execute193823772024-03-07 9:24:11402 days ago1709803451IN
0x67D19dcb...A4A146A56
0 ETH0.0053583252.27987316
Execute193809452024-03-07 4:35:47402 days ago1709786147IN
0x67D19dcb...A4A146A56
0 ETH0.006487775.95959207
Execute193747522024-03-06 7:51:23403 days ago1709711483IN
0x67D19dcb...A4A146A56
0 ETH0.0061126159.62942039
Execute193746292024-03-06 7:26:47403 days ago1709710007IN
0x67D19dcb...A4A146A56
0 ETH0.0058313956.8955115
Execute193740492024-03-06 5:29:47403 days ago1709702987IN
0x67D19dcb...A4A146A56
0 ETH0.0076539774.66563699
Execute193739552024-03-06 5:10:59403 days ago1709701859IN
0x67D19dcb...A4A146A56
0 ETH0.0067036964.13173384
Execute193619042024-03-04 12:49:35405 days ago1709556575IN
0x67D19dcb...A4A146A56
0 ETH0.0039147366.17644639
Execute193618752024-03-04 12:43:47405 days ago1709556227IN
0x67D19dcb...A4A146A56
0 ETH0.008865272.0080863
Execute193592982024-03-04 4:05:35405 days ago1709525135IN
0x67D19dcb...A4A146A56
0 ETH0.0036256861.29027316
Execute193592692024-03-04 3:59:47405 days ago1709524787IN
0x67D19dcb...A4A146A56
0 ETH0.0062946151.13541102
Execute193592472024-03-04 3:55:23405 days ago1709524523IN
0x67D19dcb...A4A146A56
0 ETH0.0054824653.50360605
Execute193459142024-03-02 7:12:35407 days ago1709363555IN
0x67D19dcb...A4A146A56
0 ETH0.0036909546.71500456
Execute193458842024-03-02 7:06:35407 days ago1709363195IN
0x67D19dcb...A4A146A56
0 ETH0.0053238242.72973247
Execute193405102024-03-01 13:05:47408 days ago1709298347IN
0x67D19dcb...A4A146A56
0 ETH0.0048442557.08322262
Execute193404272024-03-01 12:49:11408 days ago1709297351IN
0x67D19dcb...A4A146A56
0 ETH0.0033243954.09917375
Execute193403982024-03-01 12:43:11408 days ago1709296991IN
0x67D19dcb...A4A146A56
0 ETH0.0070586755.81792802
Execute193403822024-03-01 12:39:59408 days ago1709296799IN
0x67D19dcb...A4A146A56
0 ETH0.0045184653.24426604
Execute193402592024-03-01 12:15:11408 days ago1709295311IN
0x67D19dcb...A4A146A56
0 ETH0.0034387853.9924696
Execute193402332024-03-01 12:09:59408 days ago1709294999IN
0x67D19dcb...A4A146A56
0 ETH0.0054229744.0587698
Execute193402292024-03-01 12:09:11408 days ago1709294951IN
0x67D19dcb...A4A146A56
0 ETH0.0060252747.64606399
Execute193402022024-03-01 12:03:35408 days ago1709294615IN
0x67D19dcb...A4A146A56
0 ETH0.0047767546.59789975
View all transactions

View more zero value Internal Transactions in Advanced View mode

Advanced mode:
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
KresusModule

Compiler Version
v0.8.17+commit.8df45f5f

Optimization Enabled:
Yes with 100 runs

Other Settings:
default evmVersion
File 1 of 10 : KresusModule.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.17;

import "./common/Utils.sol";
import "./common/BaseModule.sol";
import "./KresusRelayer.sol";
import "./SecurityManager.sol";
import "./TransactionManager.sol";
import {IKresusRegistry} from "../infrastructure/IKresusRegistry.sol";

/**
 * @title KresusModule
 * @notice Single module for Kresus vault.
 */
contract KresusModule is BaseModule, KresusRelayer, SecurityManager, TransactionManager {

    address public immutable kresusGuardian;

    /**
     * @param _storageAddr deployed instance of storage contract
     * @param _kresusRegistry deployed instance of Kresus registry
     * @param _kresusGuardian default guardian of kresus for recovery and unblocking
     */
    constructor (
        IStorage _storageAddr,
        IKresusRegistry _kresusRegistry,
        address _kresusGuardian
    )
        BaseModule(_storageAddr, _kresusRegistry)
    {
        require(_kresusGuardian != ZERO_ADDRESS, "KM: Invalid address");
        kresusGuardian = _kresusGuardian;
    }

    /**
     * @inheritdoc IModule
     */
    function init(
        address _vault,
        bytes calldata _initData
    )
        external
        override
        onlyVault(_vault)
    {
        (address newKbg, uint256 newTimeDelay) = abi.decode(_initData, (address, uint256));
        require(IVault(_vault).owner() != newKbg, "KM: Invalid KBG");
        IVault(_vault).enableStaticCall(address(this));
        _storage.setTimeDelay(_vault, newTimeDelay);
        _storage.setKbg(_vault, newKbg);
    }

    /**
     * @inheritdoc IModule
     */
    function addModule(
        address _vault,
        address _module,
        bytes memory _initData
    )
        external
        onlySelf()
    {
        require(kresusRegistry.isRegisteredModule(_module), "KM: module is not registered");
        IVault(_vault).authoriseModule(_module, true, _initData);
    }
    
    /**
     * @inheritdoc KresusRelayer
     */
    function getRequiredSignatures(
        address _vault,
        bytes calldata _data
    )
        public
        view
        override
        returns (uint256, Signature)
    {
        bytes4 methodId = Utils.functionPrefix(_data);

        if(_storage.isLocked(_vault)) {
            require(
                methodId == SecurityManager.unlock.selector ||
                methodId == SecurityManager.executeBequeathal.selector ||
                methodId == SecurityManager.disable.selector,
                "KM: method not allowed"
            );
            if(methodId == SecurityManager.unlock.selector) {
                return (kresusRegistry.getUnlockTd(), Signature.KBGAndKWG);
            }
        }

        if(_storage.isDisabled(_vault)) {
            require(
                methodId == SecurityManager.executeBequeathal.selector ||
                methodId == TransactionManager.multiCall.selector ||
                methodId == TransactionManager.multiCallToWhitelistedAddresses.selector ||
                methodId == SecurityManager.enable.selector,
                "KM: method not allowed"
            );
        }

        if (methodId == TransactionManager.multiCall.selector) {
            bool hasHumanGuardian = _storage.hasHumanGuardian(_vault);
            return hasHumanGuardian ? 
                (_storage.getTimeDelay(_vault), Signature.HG) :
                (_storage.getTimeDelay(_vault), Signature.KBG);
        }
        if(methodId == TransactionManager.multiCallToWhitelistedAddresses.selector) {
            bool hasHumanGuardian = _storage.hasHumanGuardian(_vault);
            return hasHumanGuardian ? (0, Signature.HG) : (0, Signature.KBG);
        }
        if(methodId == SecurityManager.lock.selector) {
            return (0, Signature.KWG);
        }
        if(
            methodId == SecurityManager.setHumanGuardian.selector ||
            methodId == SecurityManager.transferOwnership.selector ||
            methodId == SecurityManager.setTimeDelay.selector
        ) {
            return (_storage.getTimeDelay(_vault), Signature.KBG);
        }
        if(
            methodId == SecurityManager.removeHumanGuardian.selector ||
            methodId == SecurityManager.removeTrustee.selector
        ) {
            return (kresusRegistry.getRemoveGuardianTd(), Signature.KBG);
        }
        if(
            methodId == SecurityManager.addHumanGuardian.selector ||
            methodId == SecurityManager.addTrustee.selector ||
            methodId == KresusModule.addModule.selector
        ) {
            return (0, Signature.KBG);
        }
        if(
            methodId == SecurityManager.enable.selector ||
            methodId == SecurityManager.disable.selector ||
            methodId == SecurityManager.executeBequeathal.selector
        ) {
            return (0, Signature.KWG);
        }
        revert("KM: unknown method");
    }

    /**
     * @param _data _data The calldata for the required transaction.
     * @return Signature The required signature from {Signature} enum.
     */
    function getCancelRequiredSignatures(
        bytes calldata _data
    )
        public
        pure
        override
        returns(Signature)
    {
        bytes4 methodId = Utils.functionPrefix(_data);
        if(
            methodId == SecurityManager.setHumanGuardian.selector ||
            methodId == SecurityManager.removeHumanGuardian.selector ||
            methodId == SecurityManager.setTimeDelay.selector ||
            methodId == SecurityManager.transferOwnership.selector ||
            methodId == SecurityManager.removeTrustee.selector ||
            methodId == TransactionManager.multiCall.selector ||
            methodId == SecurityManager.unlock.selector
        ) {
            return Signature.Owner;
        }
        revert("KM: unknown method");
    }

    /**
    * @notice Validates the signatures provided with a relayed transaction.
    * @param _vault The target vault.
    * @param _signHash The signed hash representing the relayed transaction.
    * @param _signatures The signatures as a concatenated bytes array.
    * @param _option An Signature enum indicating whether the owner is required, optional or disallowed.
    * @return A boolean indicating whether the signatures are valid.
    */
    function validateSignatures(
        address _vault,
        bytes32 _signHash,
        bytes memory _signatures,
        Signature _option
    ) 
        public 
        view
        override
        returns (bool)
    {
        if(_signatures.length < 65) {
            return false;
        }

        address signer0 = Utils.recoverSigner(_signHash, _signatures, 0);

        if(_option == Signature.Owner) {
            return signer0 == IVault(_vault).owner();
        }
        if(_option == Signature.HG) {
            return _storage.isHumanGuardian(_vault, signer0);
        }
        if(_option == Signature.KBG || _option == Signature.KBGAndKWG) {
            if(_signatures.length > 65) {
                address signer1 = Utils.recoverSigner(_signHash, _signatures, 1);
                return _storage.isKbg(_vault, signer0) && signer1 == kresusGuardian;
            }
            return _storage.isKbg(_vault, signer0);
        }
        return signer0 == kresusGuardian;
    }
}

File 2 of 10 : IKresusRegistry.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.17;

/**
 * @title IModuleRegistry
 * @notice Interface for the registry of authorised modules.
 */
interface IKresusRegistry {
    /**
     * @notice Registers a module.
     * @param _module The module.
     * @param _name The unique name of the module.
     */
    function registerModule(address _module, string calldata _name) external;

    /**
     * @notice Deregisters a module.
     * @param _module The module.
     */
    function deregisterModule(address _module) external;

    /**
     * @notice Registers contract addresses with their selectors.
     * @param _contracts Contract addresses to be whitelisted.
     * @param _selectors List of corresponding method ids to be whitelisted.
     */
    function registerContract(address[] memory _contracts, bytes4[] memory _selectors) external;
    
    /**
     * @notice Deregisters contract addresses with their selectors.
     * @param _contracts Contract addresses to be whitelisted.
     * @param _selectors List of corresponding method ids to be whitelisted.
     */
    function deregisterContract(address[] memory _contracts, bytes4[] memory _selectors) external;

    /**
     * @notice Function to set the time delay for remove guardian operation.
     * @param _td New time delay for removing guardian.
     */
    function setRemoveGuardianTd(uint256 _td) external;

    /**
     * @notice Function to set the time delay for unlock operation.
     * @param _td New time delay for unlocking a vault.
     */
    function setUnlockTd(uint256 _td) external;

    /**
     * @notice Gets the name of a module from its address.
     * @param _module The module address.
     * @return the name.
     */
    function moduleInfo(address _module) external view returns (string memory);

    /**
     * @notice Checks if a module is registered.
     * @param _module The module address.
     * @return true if the module is registered.
     */
    function isRegisteredModule(address _module) external view returns (bool);

    /**
     * @notice Checks if given modules are registered.
     * @param _modules The module addresses.
     * @return true if modules are registered.
     */
    function isRegisteredModule(address[] calldata _modules) external view returns (bool);

    /**
     * @notice Checks if given list of contracts addresses and corresponsing method ids are whitelisted.
     * @param _contracts List of contract addresses.
     * @param _sigs List of corresponding method ids.
     * @return true if all the contract addresses and method ids are whitelisted else false.
     */
    function isRegisteredCalls(address[] memory _contracts, bytes4[] memory _sigs) external view returns (bool);

    /**
     * @notice Function to get the time delay for unlock.
     * @return Time delay for unlocking a vault.
     */
    function getUnlockTd() external view returns(uint256); 


    /**
     * @notice Function to get the time delay for remove guardian.
     * @return Time delay for remove guardian.
     */
    function getRemoveGuardianTd() external view returns(uint256); 
}

File 3 of 10 : BaseModule.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.17;

import "../../vault/IVault.sol";
import "../..//storage/IStorage.sol";
import "./IModule.sol";
import {IKresusRegistry} from "../../infrastructure/IKresusRegistry.sol";
// import "hardhat/console.sol";

/**
 * @title BaseModule
 * @notice Base Module contract that contains methods common to all Modules.
 */
abstract contract BaseModule is IModule {

    // different types of signatures
    enum Signature {
        Owner,
        KBG,
        HG,
        KBGAndKWG,
        KWG
    }

    // Empty calldata
    bytes constant internal EMPTY_BYTES = "";

    // Zero address
    address constant internal ZERO_ADDRESS = address(0);

    // The guardians storage
    IStorage internal immutable _storage;

    // Module Registry address
    IKresusRegistry internal immutable kresusRegistry;

    /**
     * @notice Throws if the sender is not the module itself.
     */
    modifier onlySelf() {
        require(_isSelf(msg.sender), "BM: must be module");
        _;
    }

    /**
     * @dev Throws if the sender is not the target vault of the call.
     */
    modifier onlyVault(address _vault) {
        require(
            msg.sender == _vault,
            "BM: caller must be vault"
        );
        _;
    }

    /**
     * @param _storageAddr deployed instance of storage contract.
     * @param _kresusRegistry deployed instance of module registry contract.
     */
    constructor(
        IStorage _storageAddr,
        IKresusRegistry _kresusRegistry
    ) {
        _storage = _storageAddr;
        kresusRegistry = _kresusRegistry;
    }

    /**
     * @notice Helper method to check if an address is the module itself.
     * @param _addr - The target address.
     * @return true if locked.
     */
    function _isSelf(address _addr) internal view returns (bool) {
        return _addr == address(this);
    }

    /**
     * @notice Helper method to check if an address is the owner of a target vault.
     * @param _vault The target vault.
     * @param _addr The address.
     */
    function _isOwner(address _vault, address _addr) internal view returns (bool) {
        return IVault(_vault).owner() == _addr;
    }

    /**
     * @notice Helper method to invoke a vault.
     * @param _vault - The target vault.
     * @param _to - The target address for the transaction.
     * @param _value - The value of the transaction.
     * @param _data - The data of the transaction.
     * @return _res result of low level call from vault.
     */
    function invokeVault(
        address _vault,
        address _to,
        uint256 _value,
        bytes memory _data
    ) 
        internal
        returns
        (bytes memory _res)
    {
        bool success;
        (success, _res) = _vault.call(
            abi.encodeWithSignature(
                "invoke(address,uint256,bytes)",
                _to,
                _value,
                _data
            )
        );
        if (success && _res.length > 0) {
            (_res) = abi.decode(_res, (bytes));
        } else if (_res.length > 0) {
            assembly {
                returndatacopy(0, 0, returndatasize())
                revert(0, returndatasize())
            }
        } else if (!success) {
            revert("BM: vault invoke reverted");
        }
    }
}

File 4 of 10 : IModule.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.17;

/**
 * @title IModule
 * @notice Interface for a Module.
 */
interface IModule {

    /**	
     * @notice Adds a module to a vault. Cannot execute when vault is locked (or under recovery)	
     * @param _vault The target vault.	
     * @param _module The modules to authorise.	
     */	
    function addModule(address _vault, address _module, bytes memory _initData) external;

    /**
     * @notice Inits a Module for a vault by e.g. setting some vault specific parameters in storage.
     * @param _vault The target vault.
     * @param _initData - Data to be initialised specific to a module when it is authorized.
     */
    function init(address _vault, bytes calldata _initData) external;


    /**
     * @notice Returns whether the module implements a callback for a given static call method.
     * @param _methodId The method id.
     */
    function supportsStaticCall(bytes4 _methodId) external view returns (bool _isSupported);
}

File 5 of 10 : Utils.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.17;

/**
 * @title Utils
 * @notice Common utility methods used by modules.
 */
library Utils {

    /**
    * @notice Helper method to recover the signer at a given position from a list of concatenated signatures.
    * @param _signedHash The signed hash
    * @param _signatures The concatenated signatures.
    * @param _index The index of the signature to recover.
    * @return the signer public address.
    */
    function recoverSigner(bytes32 _signedHash, bytes memory _signatures, uint256 _index) internal pure returns (address) {
        uint8 v;
        bytes32 r;
        bytes32 s;
        // we jump 32 (0x20) as the first slot of bytes contains the length
        // we jump 65 (0x41) per signature
        // for v we load 32 bytes ending with v (the first 31 come from s) then apply a mask
        // solhint-disable-next-line no-inline-assembly
        assembly {
            r := mload(add(_signatures, add(0x20,mul(0x41,_index))))
            s := mload(add(_signatures, add(0x40,mul(0x41,_index))))
            v := and(mload(add(_signatures, add(0x41,mul(0x41,_index)))), 0xff)
        }
        require(v == 27 || v == 28, "U: bad v value in signature");

        address recoveredAddress = ecrecover(_signedHash, v, r, s);
        require(recoveredAddress != address(0), "U: ecrecover returned 0");
        return recoveredAddress;
    }

    /**
    * @notice Helper method to parse data and extract the method signature.
    * @param _data The calldata.
    * @return prefix The methodID for the calldata.
    */
    function functionPrefix(bytes memory _data) internal pure returns (bytes4 prefix) {
        require(_data.length >= 4, "U: Invalid functionPrefix");
        // solhint-disable-next-line no-inline-assembly
        assembly {
            prefix := mload(add(_data, 0x20))
        }
    }
}

File 6 of 10 : KresusRelayer.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.17;

import "./common/BaseModule.sol";
/**
 * @title KresusRelayer
 * @notice Abstract Module to execute transactions signed by ETH-less accounts and sent by a relayer.
 */
abstract contract KresusRelayer is BaseModule {

    struct RelayerConfig {
        uint256 nonce;
        mapping(bytes32 => uint256) queuedTransactions;
        mapping(bytes32 => uint256) arrayIndex;
        bytes32[] queue;
    }

    // Used to avoid stack too deep error
    struct StackExtension {
        Signature signatureRequirement;
        bytes32 signHash;
        bool success;
        bytes returnData;
    }

    uint256 internal constant BLOCKBOUND = 10000;

    mapping (address => RelayerConfig) internal relayer;


    event TransactionExecuted(address indexed vault, bool indexed success, bytes returnData, bytes32 signedHash);
    event TransactionQueued(address indexed vault, uint256 executionTime, bytes32 signedHash);
    event Refund(address indexed vault, uint256 refundAmount);
    event ActionCancelled(address indexed vault, bytes32 signedHash);
    event AllActionsCancelled(address indexed vault);
    
    /**
    * @notice Executes a relayed transaction.
    * @param _vault The target vault.
    * @param _data The data for the relayed transaction
    * @param _nonce The nonce used to prevent replay attacks.
    * @param _signatures The signatures as a concatenated byte array.
    * @return true if executed or queued successfully, else returns false.
    */
    function execute(
        address _vault,
        bytes calldata _data,
        uint256 _nonce,
        bytes calldata _signatures
    )
        external
        returns (bool)
    {
        require(verifyData(_vault, _data), "KR: Target of _data != _vault");

        StackExtension memory stack;
        uint256 td;
        (td, stack.signatureRequirement) = getRequiredSignatures(_vault, _data);

        stack.signHash = getSignHash(
            _vault,
            0,
            _data,
            _nonce
        );

        // Execute a queued tx
        if (isActionQueued(_vault, stack.signHash)){
            require(
                relayer[_vault].queuedTransactions[stack.signHash] < block.timestamp,
                "KR: Time not expired"
            );
            (stack.success, stack.returnData) = address(this).call(_data);
            require(stack.success, "KR: Internal call failed");
            if(relayer[_vault].queue.length > 0) {
                removeQueue(_vault, stack.signHash);
            }
            emit TransactionExecuted(_vault, stack.success, stack.returnData, stack.signHash);
            return stack.success;
        }
        
        
        require(validateSignatures(
                _vault, 
                stack.signHash,
                _signatures, 
                stack.signatureRequirement
            ),
            "KR: Invalid Signatures"
        );

        require(checkAndUpdateUniqueness(_vault, _nonce), "KR: Duplicate request");
        

        // Queue the Tx
        if(td > 0) {
            uint256 executionTime = block.timestamp + td;
            relayer[_vault].queuedTransactions[stack.signHash] = executionTime;
            relayer[_vault].queue.push(stack.signHash);
            relayer[_vault].arrayIndex[stack.signHash] = relayer[_vault].queue.length-1;
            emit TransactionQueued(_vault, executionTime, stack.signHash);
            return true;
        }
        // Execute the tx directly without queuing
        else {
            (stack.success, stack.returnData) = address(this).call(_data);
            require(stack.success, "KR: Internal call failed");
            emit TransactionExecuted(_vault, stack.success, stack.returnData, stack.signHash);
            return stack.success;
        }
    }  

    /**
     * @notice cancels a transaction which was queued.
     * @param _vault The target vault.
     * @param _data The data for the relayed transaction.
     * @param _nonce The nonce used to prevent replay attacks.
     * @param _signature The signature needed to validate cancel.
     */
    function cancel(
        address _vault,
        bytes calldata _data,
        uint256 _nonce,
        bytes memory _signature
    ) 
        external 
    {
        bytes32 _actionHash = getSignHash(_vault, 0, _data, _nonce);
        bytes32 _cancelHash = getSignHash(_vault, 0, "0x", _nonce);
        require(isActionQueued(_vault, _actionHash), "KR: Invalid hash");
        Signature _sig = getCancelRequiredSignatures(_data);
        require(
            validateSignatures(
                _vault,
                _cancelHash,
                _signature,
                _sig
            ), "KR: Invalid Signatures"
        );
        removeQueue(_vault, _actionHash);
        emit ActionCancelled(_vault, _actionHash);
    }

    /**
     * @notice to cancel all the queued operations for a `_vault` address.
     * @param _vault The target vault.
     */
    function cancelAll(
        address _vault
    ) external onlySelf {
        uint256 len = relayer[_vault].queue.length; 
        for(uint256 i=0;i<len;i++) {
            bytes32 _actionHash = relayer[_vault].queue[i];
            relayer[_vault].queuedTransactions[_actionHash] = 0;
            relayer[_vault].arrayIndex[_actionHash] = 0;
        }
        delete relayer[_vault].queue;
        emit AllActionsCancelled(_vault);
    }

    /**
    * @notice Gets the current nonce for a vault.
    * @param _vault The target vault.
    * @return nonce gets the last used nonce of the vault.
    */
    function getNonce(address _vault) external view returns (uint256 nonce) {
        return relayer[_vault].nonce;
    }

    /**
    * @notice Gets the number of valid signatures that must be provided to execute a
    * specific relayed transaction.
    * @param _vault The target vault.
    * @param _data The data of the relayed transaction.
    * @return The number of required signatures and the vault owner signature requirement.
    */
    function getRequiredSignatures(
        address _vault,
        bytes calldata _data
    ) public view virtual returns (uint256, Signature);

    /**
    * @notice checks validity of a signature depending on status of the vault.
    * @param _vault The target vault.
    * @param _actionHash signed hash of the request.
    * @param _data The data of the relayed transaction.
    * @param _option Type of signature.
    * @return true if it is a valid signature.
    */
    function validateSignatures(
        address _vault,
        bytes32 _actionHash,
        bytes memory _data,
        Signature _option
    ) public view virtual returns(bool);

    /**
    * @notice Gets the required signature from {Signature} enum to cancel the request.
    * @param _data The data of the relayed transaction.
    * @return The required signature from {Signature} enum .
    */ 
    function getCancelRequiredSignatures(
        bytes calldata _data
    ) public pure virtual returns(Signature);

    /**
    * @notice Generates the signed hash of a relayed transaction according to ERC 1077.
    * @param _from The starting address for the relayed transaction (should be the relayer module)
    * @param _value The value for the relayed transaction.
    * @param _data The data for the relayed transaction which includes the vault address.
    * @param _nonce The nonce used to prevent replay attacks.
    */
    function getSignHash(
        address _from,
        uint256 _value,
        bytes memory _data,
        uint256 _nonce
    )
        public
        view
        returns (bytes32)
    {
        return keccak256(
            abi.encodePacked(
                "\x19Ethereum Signed Message:\n32",
                keccak256(abi.encodePacked(
                    bytes1(0x19),
                    bytes1(0),
                    _from,
                    _value,
                    _data,
                    block.chainid,
                    _nonce
                ))
            )
        );
    }

    /**
    * @notice Checks if the relayed transaction is unique. If yes the state is updated.
    * @param _vault The target vault.
    * @param _nonce The nonce.
    * @return true if the transaction is unique.
    */
    function checkAndUpdateUniqueness(
        address _vault,
        uint256 _nonce
    )
        internal
        returns (bool)
    {
        // use the incremental nonce
        if (_nonce <= relayer[_vault].nonce) {
            return false;
        }
        uint256 nonceBlock = (_nonce & 0xffffffffffffffffffffffffffffffff00000000000000000000000000000000) >> 128;
        if (nonceBlock > block.number + BLOCKBOUND) {
            return false;
        }
        relayer[_vault].nonce = _nonce;
        return true;
    }

    /**
    * @notice Checks that the vault address provided as the first parameter of _data matches _vault
    * @return false if the addresses are different.
    */
    function verifyData(address _vault, bytes calldata _data) internal pure returns (bool) {
        require(_data.length >= 36, "KR: Invalid dataVault");
        require(_vault != ZERO_ADDRESS, "KR: Invalid vault");
        address dataVault = abi.decode(_data[4:], (address));
        return dataVault == _vault;
    }

    /**
    * @notice Check whether a given action is queued.
    * @param _vault The target vault.
    * @param  actionHash  Hash of the action to be checked. 
    * @return Boolean `true` if the underlying action of `actionHash` is queued, otherwise `false`.
    */
    function isActionQueued(
        address _vault,
        bytes32 actionHash
    )
        public
        view
        returns (bool)
    {
        return (relayer[_vault].queuedTransactions[actionHash] > 0);
    }

    /**
    * @notice Return execution time for a given queued action.
    * @param _vault The target vault.
    * @param  actionHash  Hash of the action to be checked.
    * @return uint256   execution time for a given queued action.
    */
    function queuedActionExecutionTime(
        address _vault,
        bytes32 actionHash
    )
        external
        view
        returns (uint256)
    {
        return relayer[_vault].queuedTransactions[actionHash];
    }
    
    /**
    * @notice Removes an element at index from the array queue of a user
    * @param _vault The target vault.
    * @param  _actionHash  Hash of the action to be checked.
    * @return false if the index is invalid.
    */
    function removeQueue(address _vault, bytes32 _actionHash) internal returns(bool) {
        RelayerConfig storage _relayer = relayer[_vault];
        _relayer.queuedTransactions[_actionHash] = 0;

        uint256 index = _relayer.arrayIndex[_actionHash];
        uint256 len = _relayer.queue.length;
        if(index != len - 1) {
            bytes32 lastHash = _relayer.queue[len - 1];
            _relayer.arrayIndex[lastHash] = index;
            _relayer.arrayIndex[_actionHash] = 0;
            _relayer.queue[index] = lastHash;
        }
        _relayer.queue.pop();
        
        return true;
    }
}

File 7 of 10 : SecurityManager.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.17;

import "./common/BaseModule.sol";
import "../vault/IVault.sol";

/**
 * @title SecurityManager
 * @notice Abstract module implementing the key security features of the vault: guardians, lock and recovery.
 */
abstract contract SecurityManager is BaseModule {

    event Bequeathed(address indexed vault, address indexed newOwner, address newKbg);
    event TransferedOwnership(address indexed vault, address newOwner, address newKbg);
    event Locked(address indexed vault);
    event Unlocked(address indexed vault);
    event HumanGuardianChanged(address indexed vault, address indexed guardian);
    event TrusteeChanged(address indexed vault, address indexed trustee);
    event TimeDelayChanged(address indexed vault, uint256 newTimeDelay);
    event Enabled(address indexed vault, address kbg);
    event Disabled(address indexed vault);

    /**
     * @notice Lets a guardian lock a vault.
     * @param _vault The target vault.
     */
    function lock(address _vault) external onlySelf() {
        _storage.lock(_vault);
        (bool success, ) = address(this).call(
            abi.encodeWithSignature("cancelAll(address)", _vault)
        );
        require(success, "SM: cancel all operation failed");
        emit Locked(_vault);
    }

    /**
     * @notice Updates the TimeDelay
     * @param _vault The target vault.
     * @param _newTimeDelay The new DelayTime to update.
     */
    function setTimeDelay(
        address _vault,
        uint256 _newTimeDelay
    )
        external
        onlySelf()
    {
        _storage.setTimeDelay(_vault, _newTimeDelay);
        emit TimeDelayChanged(_vault, _newTimeDelay);
    }

    /**
     * @notice Lets a guardian unlock a locked vault.
     * @param _vault The target vault.
     */
    function unlock(
        address _vault
    ) 
        external
        onlySelf()
    {
        _storage.unlock(_vault);
        emit Unlocked(_vault);
    }


    /**
     * @notice Lets the owner add a guardian to its vault.
     * @param _vault The target vault.
     * @param _guardian The guardian to add.
     */
    function setHumanGuardian(
        address _vault,
        address _guardian
    )
        external
        onlySelf()
    {
        require(_guardian != IVault(_vault).owner(), "SM: Invalid guardian");
        _storage.setHumanGuardian(_vault, _guardian);
        emit HumanGuardianChanged(_vault, _guardian);
    }

    /**
     * @notice Function to be used to remove human guardians.
     * @param _vault The target vault.
     */
    function removeHumanGuardian(
        address _vault
    )
        external
        onlySelf()
    {
        _storage.setHumanGuardian(_vault, ZERO_ADDRESS);
        emit HumanGuardianChanged(_vault, ZERO_ADDRESS);
    }

    /**
     * @notice Function to add a human guardian to vault.
     * @param _vault The target vault.
     * @param _guardian Address of the new guardian.
     */
    function addHumanGuardian(
        address _vault,
        address _guardian
    )
        external
        onlySelf()
    {
        require(
            _storage.getHumanGuardian(_vault) == ZERO_ADDRESS,
            "SM: Cannot add guardian"
        );
        _storage.setHumanGuardian(_vault, _guardian);
        emit HumanGuardianChanged(_vault, _guardian);
    }

    /**
     * @notice Changes trustee address for a vault.
     * @param _vault The target vault.
     * @param _newTrustee Address of the new trustee.
     */
    function addTrustee(
        address _vault,
        address _newTrustee
    ) 
        external
        onlySelf()
    {
        require(
            _storage.getTrustee(_vault) == ZERO_ADDRESS && _newTrustee != ZERO_ADDRESS,
            "SM: Cannot add trustee"
        );
        _storage.setTrustee(_vault, _newTrustee);
        emit TrusteeChanged(_vault, _newTrustee);
    }

    /**
     * @notice Resets the trustee address.
     * @param _vault The target vault.
     */
    function removeTrustee(
        address _vault
    )
        external
        onlySelf()
    {
        _storage.setTrustee(_vault, ZERO_ADDRESS);
        emit TrusteeChanged(_vault, ZERO_ADDRESS);
    }

    /**
     * @notice Sets the current trustee address as the new owner for the vault. 
     * After change in owner sets the current trustee address to 0x0.
     * @param _vault The target vault.
     * @param _newKbg The new KBG address.
     */
    function executeBequeathal(
        address _vault,
        address _newKbg
    )
        external
        onlySelf()
    {
        address trustee = _storage.getTrustee(_vault);
        resetVault(_vault, trustee, _newKbg);
        emit Bequeathed(_vault, trustee, _newKbg);
    }

    /**
     * @notice Enables target vault.
     * @param _vault The target vault.
     * @param _newKbg New KBG address.
     */
    function enable(
        address _vault,
        address _newKbg
    )
        external
        onlySelf()
    {
        _storage.enable(_vault, _newKbg);
        emit Enabled(_vault, _newKbg);
    }

    /**
     * @notice Disables target vault.
     * @param _vault The target vault.
     */
    function disable(
        address _vault
    )
        external
        onlySelf()
    {
        _storage.disable(_vault);
        emit Disabled(_vault);
    }

    /**
     * @notice Transfers ownership to different address and changes the kbg address.
     * @param _vault The target vault.
     * @param _newKbg The new kbg address.
     * @param _newOwner The new owner address.
     */
    function transferOwnership(
        address _vault,
        address _newOwner,
        address _newKbg
    )
        external
        onlySelf()
    {
        resetVault(_vault, _newOwner, _newKbg);
        emit TransferedOwnership(_vault, _newOwner, _newKbg);
    }

    /**
     * @notice Changes owner, and resets vault to default state.
     * @param _vault The target vault.
     * @param _newOwner The new owner address.
     * @param _newKbg The new kbg address.
     */
    function resetVault(
        address _vault,
        address _newOwner,
        address _newKbg
    )
        internal
    {
        changeOwner(_vault, _newOwner);
        _storage.reset(_vault);
        _storage.setKbg(_vault, _newKbg);
    }

    /**
     * @notice Changes the owner address for a vault.
     * @param _vault The target vault.
     * @param _newOwner Address of the new owner.
     */
    function changeOwner(address _vault, address _newOwner) internal {
        validateNewOwner(_vault, _newOwner);
        IVault(_vault).setOwner(_newOwner);
        (bool success, ) = address(this).call(
            abi.encodeWithSignature("cancelAll(address)", _vault)
        );
        require(success, "SM: cancel all operation failed");
    }

    /**
     * @notice Checks if the vault address is valid to be a new owner.
     * @param _vault The target vault.
     * @param _newOwner The target vault.
     */
    function validateNewOwner(
        address _vault,
        address _newOwner
    ) internal view {
        require(
            !_storage.isHumanGuardian(
                _vault,
                _newOwner
            ),
            "SM: new owner cannot be guardian"
        );
    }
}

File 8 of 10 : TransactionManager.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.17;

import "./common/Utils.sol";
import "./common/BaseModule.sol";

/**
 * @title TransactionManager
 * @notice Module to execute transactions in sequence to e.g. transfer tokens (ETH, ERC20, ERC721, ERC1155)
 * or call third-party contracts.
 */
abstract contract TransactionManager is BaseModule {

    struct Call {
        address to;      //the target address to which transaction to be sent
        uint256 value;   //native amount to be sent.
        bytes data;      //the data for the transaction.
    }

    // Static calls
    bytes4 private constant ERC1271_IS_VALID_SIGNATURE = bytes4(keccak256("isValidSignature(bytes32,bytes)"));
    bytes4 private constant ERC721_RECEIVED = bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"));
    bytes4 private constant ERC1155_RECEIVED = bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"));
    bytes4 private constant ERC1155_BATCH_RECEIVED = bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"));
    bytes4 private constant ERC165_INTERFACE = bytes4(keccak256("supportsInterface(bytes4)"));

    /**
     * @notice Makes the target vault execute a sequence of transactions
     * The method reverts if any of the inner transactions reverts.
     * @param _vault The target vault.
     * @param _transactions The sequence of transactions.
     * @return bytes array of results for  all low level calls.
     */
    function multiCall(
        address _vault,
        Call[] calldata _transactions
    )
        external 
        onlySelf()
        returns (bytes[] memory)
    {
        return multiCallWithApproval(_vault, _transactions);
    }

    /**
     * @notice Makes the target vault execute a sequence of transactions to only whitelisted addresses.
     * The method reverts if there are any transactions to non whitelisted addresses.
     * The method reverts if any of the inner transactions reverts.
     * @param _vault The target vault.
     * @param _transactions The sequence of transactions.
     * @return bytes array of results for all low level calls.
     */
    function multiCallToWhitelistedAddresses(
        address _vault,
        Call[] calldata _transactions
    )
        external
        onlySelf()
        returns (bytes[] memory)
    {
        uint256 len = _transactions.length;
        address[] memory to = new address[](len);
        bytes4[] memory sigs = new bytes4[](len);
        for(uint256 i=0;i<len;i++) {
            to[i] = _transactions[i].to;
            sigs[i] = Utils.functionPrefix(_transactions[i].data);
        }
        require(kresusRegistry.isRegisteredCalls(to, sigs), "TM: Addresses or Sigs not registered");
        return multiCallWithApproval(_vault, _transactions);
    }

    /**
     * @inheritdoc IModule
     */
    function supportsStaticCall(
        bytes4 _methodId
    )
        external
        pure
        override
        returns (bool _isSupported)
    {
        return _methodId == ERC1271_IS_VALID_SIGNATURE ||
               _methodId == ERC721_RECEIVED ||
               _methodId == ERC165_INTERFACE ||
               _methodId == ERC1155_RECEIVED ||
               _methodId == ERC1155_BATCH_RECEIVED;
    }

    /**
     * @notice Returns true if this contract implements the interface defined by
     * `interfaceId` (see https://eips.ethereum.org/EIPS/eip-165).
     */
    function supportsInterface(
        bytes4 _interfaceID
    )
        external
        pure
        returns (bool)
    {
        return  _interfaceID == ERC165_INTERFACE || _interfaceID == (ERC1155_RECEIVED ^ ERC1155_BATCH_RECEIVED);          
    }

    /**
    * @notice Implementation of EIP 1271.
    * Should return whether the signature provided is valid for the provided data.
    * @param _msgHash Hash of a message signed on the behalf of address(this)
    * @param _signature Signature byte array associated with _msgHash
    */
    function isValidSignature(
        bytes32 _msgHash,
        bytes memory _signature
    )
        external
        view
        returns (bytes4)
    {
        require(_signature.length == 65, "TM: invalid signature length");
        address signer = Utils.recoverSigner(_msgHash, _signature, 0);
        require(_isOwner(msg.sender, signer), "TM: Invalid signer");
        return ERC1271_IS_VALID_SIGNATURE;
    }


    function multiCallWithApproval(
        address _vault,
        Call[] calldata _transactions
    ) 
        internal
        returns
        (bytes[] memory)
    {
        bytes[] memory results = new bytes[](_transactions.length);
        for(uint256 i = 0; i < _transactions.length; i++) {
            results[i] = invokeVault(
                _vault,
                _transactions[i].to,
                _transactions[i].value,
                _transactions[i].data
            );
        }
        return results;
    }


    fallback() external {
        bytes4 methodId = Utils.functionPrefix(msg.data);
        if(methodId == ERC721_RECEIVED || methodId == ERC1155_RECEIVED || methodId == ERC1155_BATCH_RECEIVED) {
            // solhint-disable-next-line no-inline-assembly
            assembly {                
                calldatacopy(0, 0, 0x04)
                return (0, 0x20)
            }
        }
    }
}

File 9 of 10 : IStorage.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.17;

/**
 * @title IStorage
 * @notice Interface for Storage
 */
interface IStorage {

    /**
     * @notice Sets lock for a vault contract.
     * @param _vault - The target vault.
     */
    function lock(address _vault) external;

    /**
     * @notice Unlocks a vault contract.
     * @param _vault - The target vault.
     */
    function unlock(address _vault) external;

    /**
     * @notice Lets an authorised module add a guardian to a vault.
     * @param _vault - The target vault.
     * @param _guardian - The guardian to add.
     */
    function setHumanGuardian(address _vault, address _guardian) external;

    /**
     * @notice Sets a new time delay for a vault contract.
     * @param _vault - The target vault.
     * @param _newTimeDelay - The new time delay.
     */
    function setTimeDelay(address _vault, uint256 _newTimeDelay) external;

    /**
     * @notice Function to be used to add trustee address to bequeath vault ownership.
     * @param _vault - The target vault.
     * @param _newTrustee - New address for trustee.
     */
    function setTrustee(address _vault, address _newTrustee) external;

    /**
     * @notice Function to set the kbg for a vault.
     * @param _vault - The target vault.
     * @param _kbg - Address of kbg.
     */
    function setKbg(address _vault, address _kbg) external;

    /**
     * @notice Function to enable or disable a vault.
     * @param _vault - The target vault.
     */
    function enable(address _vault, address _kbg) external;

    /**
     * @notice Function to disable a vault.
     * @param _vault - The target vault.
     */
    function disable(address _vault) external;

    /**
     * @notice Function to reset the vault.
     * @param _vault - The target vault.
     */
    function reset(address _vault) external;

    /**
     * @notice Returns boolean indicating state of the vault.
     * @param _vault - The target vault.
     * @return true if the vault is locked, else returns false.
     */
    function isLocked(address _vault) external view returns(bool);

    /**
     * @notice Returns kbg address of the vault.
     * @param _vault - The target vault.
     * @return kbg address of the vault.
     */
    function getKbg(address _vault) external view returns(address);

    /**
     * @notice Returns human guardian address of the vault.
     * @param _vault - The target vault.
     */
    function getHumanGuardian(address _vault) external view returns(address);

    /**
     * @notice Returns the trustee address for a vault.
     * @param _vault - The target vault.
     */
    function getTrustee(address _vault) external view returns(address);

    /**
     * @notice Checks if an address is kbg for a vault.
     * @param _vault - The target vault.
     * @param _kbg - The account address to be checked.
     * @return true if `_kbg` is kbg for `_vault`.
     */
    function isKbg(address _vault, address _kbg) external view returns(bool);

    /**
     * @notice Checks if an address is a guardian for a vault.
     * @param _vault - The target vault.
     * @param _guardian - The account address to be checked.
     * @return true if `_guardian` is human guardian for `_vault`.
     */
    function isHumanGuardian(address _vault, address _guardian) external view returns(bool);

    /**
     * @notice Checks if an address is an trustee for a vault.
     * @param _vault - The target vault.
     * @param _trustee - The account address to be checked.
     * return true if `_trustee` is the trustee for `_vault`.
     */
    function isTrustee(address _vault, address _trustee) external view returns(bool);

    /**
     * @notice Returns if a vault is disabled.
     * @param _vault - The target vault.
     * return true if the vault is disabled else return false.
     */
    function isDisabled(address _vault) external view returns(bool);

    /**
     * @notice Returns uint256 time delay in seconds for a vault
     * @param _vault - The target vault.
     * @return uint256 time delay in seconds for a vault.
     */
    function getTimeDelay(address _vault) external view returns(uint256);

    /**
     * @notice Returns if a vault has human guardian.
     * @param _vault - The target vault.
     * @return true if `_vault` has human guardian else false.
     */
    function hasHumanGuardian(address _vault) external view returns(bool);
}

File 10 of 10 : IVault.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.17;

/**
 * @title IVault
 * @notice Interface for the BaseVault
 */
interface IVault {

    /**
     * @notice Enables/Disables a module.
     * @param _module The target module.
     * @param _value Set to `true` to authorise the module.
     */
    function authoriseModule(address _module, bool _value, bytes memory _initData) external;

    /**
     * @notice Enables a static method by specifying the target module to which the call must be delegated.
     * @param _module The target module.
     */
    function enableStaticCall(address _module) external;


    /**
     * @notice Inits the vault by setting the owner and authorising a list of modules.
     * @param _owner The owner.
     * @param _initData bytes32 initialization data specific to the module.
     * @param _modules The modules to authorise.
     */
    function init(address _owner, address[] calldata _modules, bytes[] calldata _initData) external;

    /**
     * @notice Sets a new owner for the vault.
     * @param _newOwner The new owner.
     */
    function setOwner(address _newOwner) external;

    /**
     * @notice Returns the vault owner.
     * @return The vault owner address.
     */
    function owner() external view returns (address);

    /**
     * @notice Returns the number of authorised modules.
     * @return The number of authorised modules.
     */
    function modules() external view returns (uint256);

    /**
     * @notice Checks if a module is authorised on the vault.
     * @param _module The module address to check.
     * @return `true` if the module is authorised, otherwise `false`.
     */
    function authorised(address _module) external view returns (bool);

    /**
     * @notice Returns the module responsible, if static call is enabled for `_sig`, otherwise return zero address.
     * @param _sig The signature of the static call.
     * @return the module doing the redirection or zero address
     */
    function enabled(bytes4 _sig) external view returns (address);
}

Settings
{
  "optimizer": {
    "enabled": true,
    "runs": 100
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "libraries": {}
}

Contract Security Audit

Contract ABI

API
[{"inputs":[{"internalType":"contract IStorage","name":"_storageAddr","type":"address"},{"internalType":"contract IKresusRegistry","name":"_kresusRegistry","type":"address"},{"internalType":"address","name":"_kresusGuardian","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"vault","type":"address"},{"indexed":false,"internalType":"bytes32","name":"signedHash","type":"bytes32"}],"name":"ActionCancelled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"vault","type":"address"}],"name":"AllActionsCancelled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"vault","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"},{"indexed":false,"internalType":"address","name":"newKbg","type":"address"}],"name":"Bequeathed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"vault","type":"address"}],"name":"Disabled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"vault","type":"address"},{"indexed":false,"internalType":"address","name":"kbg","type":"address"}],"name":"Enabled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"vault","type":"address"},{"indexed":true,"internalType":"address","name":"guardian","type":"address"}],"name":"HumanGuardianChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"vault","type":"address"}],"name":"Locked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"vault","type":"address"},{"indexed":false,"internalType":"uint256","name":"refundAmount","type":"uint256"}],"name":"Refund","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"vault","type":"address"},{"indexed":false,"internalType":"uint256","name":"newTimeDelay","type":"uint256"}],"name":"TimeDelayChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"vault","type":"address"},{"indexed":true,"internalType":"bool","name":"success","type":"bool"},{"indexed":false,"internalType":"bytes","name":"returnData","type":"bytes"},{"indexed":false,"internalType":"bytes32","name":"signedHash","type":"bytes32"}],"name":"TransactionExecuted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"vault","type":"address"},{"indexed":false,"internalType":"uint256","name":"executionTime","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"signedHash","type":"bytes32"}],"name":"TransactionQueued","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"vault","type":"address"},{"indexed":false,"internalType":"address","name":"newOwner","type":"address"},{"indexed":false,"internalType":"address","name":"newKbg","type":"address"}],"name":"TransferedOwnership","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"vault","type":"address"},{"indexed":true,"internalType":"address","name":"trustee","type":"address"}],"name":"TrusteeChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"vault","type":"address"}],"name":"Unlocked","type":"event"},{"stateMutability":"nonpayable","type":"fallback"},{"inputs":[{"internalType":"address","name":"_vault","type":"address"},{"internalType":"address","name":"_guardian","type":"address"}],"name":"addHumanGuardian","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_vault","type":"address"},{"internalType":"address","name":"_module","type":"address"},{"internalType":"bytes","name":"_initData","type":"bytes"}],"name":"addModule","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_vault","type":"address"},{"internalType":"address","name":"_newTrustee","type":"address"}],"name":"addTrustee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_vault","type":"address"},{"internalType":"bytes","name":"_data","type":"bytes"},{"internalType":"uint256","name":"_nonce","type":"uint256"},{"internalType":"bytes","name":"_signature","type":"bytes"}],"name":"cancel","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_vault","type":"address"}],"name":"cancelAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_vault","type":"address"}],"name":"disable","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_vault","type":"address"},{"internalType":"address","name":"_newKbg","type":"address"}],"name":"enable","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_vault","type":"address"},{"internalType":"bytes","name":"_data","type":"bytes"},{"internalType":"uint256","name":"_nonce","type":"uint256"},{"internalType":"bytes","name":"_signatures","type":"bytes"}],"name":"execute","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_vault","type":"address"},{"internalType":"address","name":"_newKbg","type":"address"}],"name":"executeBequeathal","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"getCancelRequiredSignatures","outputs":[{"internalType":"enum BaseModule.Signature","name":"","type":"uint8"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"_vault","type":"address"}],"name":"getNonce","outputs":[{"internalType":"uint256","name":"nonce","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_vault","type":"address"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"getRequiredSignatures","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"enum BaseModule.Signature","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"uint256","name":"_value","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"},{"internalType":"uint256","name":"_nonce","type":"uint256"}],"name":"getSignHash","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_vault","type":"address"},{"internalType":"bytes","name":"_initData","type":"bytes"}],"name":"init","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_vault","type":"address"},{"internalType":"bytes32","name":"actionHash","type":"bytes32"}],"name":"isActionQueued","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_msgHash","type":"bytes32"},{"internalType":"bytes","name":"_signature","type":"bytes"}],"name":"isValidSignature","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"kresusGuardian","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_vault","type":"address"}],"name":"lock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_vault","type":"address"},{"components":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct TransactionManager.Call[]","name":"_transactions","type":"tuple[]"}],"name":"multiCall","outputs":[{"internalType":"bytes[]","name":"","type":"bytes[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_vault","type":"address"},{"components":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct TransactionManager.Call[]","name":"_transactions","type":"tuple[]"}],"name":"multiCallToWhitelistedAddresses","outputs":[{"internalType":"bytes[]","name":"","type":"bytes[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_vault","type":"address"},{"internalType":"bytes32","name":"actionHash","type":"bytes32"}],"name":"queuedActionExecutionTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_vault","type":"address"}],"name":"removeHumanGuardian","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_vault","type":"address"}],"name":"removeTrustee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_vault","type":"address"},{"internalType":"address","name":"_guardian","type":"address"}],"name":"setHumanGuardian","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_vault","type":"address"},{"internalType":"uint256","name":"_newTimeDelay","type":"uint256"}],"name":"setTimeDelay","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"_interfaceID","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes4","name":"_methodId","type":"bytes4"}],"name":"supportsStaticCall","outputs":[{"internalType":"bool","name":"_isSupported","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"_vault","type":"address"},{"internalType":"address","name":"_newOwner","type":"address"},{"internalType":"address","name":"_newKbg","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_vault","type":"address"}],"name":"unlock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_vault","type":"address"},{"internalType":"bytes32","name":"_signHash","type":"bytes32"},{"internalType":"bytes","name":"_signatures","type":"bytes"},{"internalType":"enum BaseModule.Signature","name":"_option","type":"uint8"}],"name":"validateSignatures","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"}]

60e06040523480156200001157600080fd5b506040516200464f3803806200464f8339810160408190526200003491620000c9565b6001600160a01b0380841660805280831660a05281166200009b5760405162461bcd60e51b815260206004820152601360248201527f4b4d3a20496e76616c6964206164647265737300000000000000000000000000604482015260640160405180910390fd5b6001600160a01b031660c052506200011d9050565b6001600160a01b0381168114620000c657600080fd5b50565b600080600060608486031215620000df57600080fd5b8351620000ec81620000b0565b6020850151909350620000ff81620000b0565b60408501519092506200011281620000b0565b809150509250925092565b60805160a05160c05161442962000226600039600081816104c001528181611b770152611c0401526000818161088f01528181610f080152818161149701526121a301526000818161060501528181610a9901528181610bff01528181610cdc01528181610e0d01528181610fab015281816110d90152818161116d01528181611201015281816112b7015281816113df0152818161162e0152818161187f01528181611a0e01528181611af601528181611bcb01528181612309015281816123e3015281816126420152818161273a0152818161297c015281816129ef01528181612cf101528181612dcb0152818161325c015281816132d8015261379c01526144296000f3fe608060405234801561001057600080fd5b506004361061019a5760003560e01c8063694c596b116100e4578063a5efb23511610092578063a5efb2351461046f578063ac419cfc14610482578063c0d91eaf14610495578063c10cab45146104a8578063cbb98bee146104bb578063ce1d3e2f146104ef578063e6c09edf1461050f578063f435f5a7146105225761019a565b8063694c596b146103ea5780636b760a94146103fd5780636c459a281461041057806371bf3af11461042357806375033f4b146104365780638a85073b1461044957806397e8f7171461045c5761019a565b80632d0335ab1161014c5780632d0335ab1461032e5780632f6c493c14610357578063304e0bb01461036a5780633b73d67f1461037d5780634c8541261461039e5780635ad5f3e4146103b15780635d80f160146103c457806368769fd8146103d75761019a565b806301ffc9a71461023b5780630312050614610263578063075a6444146102765780630a6dd219146102965780631626ba7e146102dc57806319a145c71461030857806325b509341461031b575b60006101dc6000368080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061053592505050565b90506001600160e01b03198116630a85bd0160e11b148061020d57506001600160e01b0319811663f23a6e6160e01b145b8061022857506001600160e01b0319811663bc197c8160e01b145b156102395760046000803760206000f35b005b61024e61024936600461389f565b610592565b60405190151581526020015b60405180910390f35b6102396102713660046138de565b6105c9565b6102896102843660046138fb565b6106a8565b60405161025a91906139d2565b6102ce6102a4366004613a34565b6001600160a01b039190911660009081526020818152604080832093835260019093019052205490565b60405190815260200161025a565b6102ef6102ea366004613b23565b610977565b6040516001600160e01b0319909116815260200161025a565b610239610316366004613a34565b610a4e565b61024e61032936600461389f565b610b3c565b6102ce61033c3660046138de565b6001600160a01b031660009081526020819052604090205490565b6102396103653660046138de565b610bc3565b610239610378366004613b69565b610c9d565b61039061038b366004613bea565b610daf565b60405161025a929190613c76565b6102396103ac366004613b69565b6115f2565b6102ce6103bf366004613c8a565b6116d0565b61024e6103d2366004613a34565b61175e565b6102396103e5366004613b69565b61178a565b61024e6103f8366004613cea565b611924565b61023961040b366004613d59565b611c42565b61024e61041e366004613da4565b611cba565b610239610431366004613e2f565b612167565b6102396104443660046138de565b6122cd565b610239610457366004613b69565b6123ac565b61023961046a3660046138de565b6124b1565b61028961047d3660046138fb565b6125d9565b610239610490366004613b69565b61260b565b6102396104a3366004613bea565b6127df565b6102396104b6366004613e90565b612a62565b6104e27f000000000000000000000000000000000000000000000000000000000000000081565b60405161025a9190613f15565b6105026104fd366004613f29565b612bac565b60405161025a9190613f6a565b61023961051d3660046138de565b612cb5565b6102396105303660046138de565b612d8f565b600060048251101561058a5760405162461bcd60e51b81526020600482015260196024820152780aa744092dcecc2d8d2c840cceadcc6e8d2dedca0e4caccd2f603b1b60448201526064015b60405180910390fd5b506020015190565b60006001600160e01b031982166301ffc9a760e01b14806105c357506001600160e01b03198216630271189760e51b145b92915050565b6105d233612f1f565b6105ee5760405162461bcd60e51b815260040161058190613f78565b60405163da209d5160e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063da209d519061063d908490600090600401613fa4565b600060405180830381600087803b15801561065757600080fd5b505af115801561066b573d6000803e3d6000fd5b5050604051600092506001600160a01b03841691507f313fbef49831f81de756df207bd6dd33dc4f5757ebd556a3375e05c1050c3aa4908390a350565b60606106b333612f1f565b6106cf5760405162461bcd60e51b815260040161058190613f78565b816000816001600160401b038111156106ea576106ea613a60565b604051908082528060200260200182016040528015610713578160200160208202803683370190505b5090506000826001600160401b0381111561073057610730613a60565b604051908082528060200260200182016040528015610759578160200160208202803683370190505b50905060005b838110156108775786868281811061077957610779613fbe565b905060200281019061078b9190613fd4565b6107999060208101906138de565b8382815181106107ab576107ab613fbe565b60200260200101906001600160a01b031690816001600160a01b03168152505061083a8787838181106107e0576107e0613fbe565b90506020028101906107f29190613fd4565b610800906040810190613ff4565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061053592505050565b82828151811061084c5761084c613fbe565b6001600160e01b0319909216602092830291909101909101528061086f81614050565b91505061075f565b50604051634ab00efb60e01b81526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690634ab00efb906108c69085908590600401614069565b602060405180830381865afa1580156108e3573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061090791906140f7565b61095f5760405162461bcd60e51b8152602060048201526024808201527f544d3a20416464726573736573206f722053696773206e6f7420726567697374604482015263195c995960e21b6064820152608401610581565b61096a878787612f2d565b93505050505b9392505050565b600081516041146109ca5760405162461bcd60e51b815260206004820152601c60248201527f544d3a20696e76616c6964207369676e6174757265206c656e677468000000006044820152606401610581565b60006109d88484600061308d565b90506109e433826131bc565b610a255760405162461bcd60e51b81526020600482015260126024820152712a269d1024b73b30b634b21039b4b3b732b960711b6044820152606401610581565b507f1626ba7e356f5979dd355a3d2bfb43e80420a480c3b854edce286a82d74968699392505050565b610a5733612f1f565b610a735760405162461bcd60e51b815260040161058190613f78565b6040516319a145c760e01b81526001600160a01b038381166004830152602482018390527f000000000000000000000000000000000000000000000000000000000000000016906319a145c790604401600060405180830381600087803b158015610add57600080fd5b505af1158015610af1573d6000803e3d6000fd5b50505050816001600160a01b03167fcbe22d4428901024069c2997f8626afe4fe1a1e280a8de9618d51351b9b265b782604051610b3091815260200190565b60405180910390a25050565b60006001600160e01b03198216630b135d3f60e11b1480610b6d57506001600160e01b03198216630a85bd0160e11b145b80610b8857506001600160e01b031982166301ffc9a760e01b145b80610ba357506001600160e01b0319821663f23a6e6160e01b145b806105c357506001600160e01b0319821663bc197c8160e01b1492915050565b610bcc33612f1f565b610be85760405162461bcd60e51b815260040161058190613f78565b604051630bdb124f60e21b81526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690632f6c493c90610c34908490600401613f15565b600060405180830381600087803b158015610c4e57600080fd5b505af1158015610c62573d6000803e3d6000fd5b50506040516001600160a01b03841692507f7e6adfec7e3f286831a0200a754127c171a2da564078722cb97704741bbdb0ea9150600090a250565b610ca633612f1f565b610cc25760405162461bcd60e51b815260040161058190613f78565b604051630435586b60e11b81526000906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063086ab0d690610d11908690600401613f15565b602060405180830381865afa158015610d2e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d529190614119565b9050610d5f83828461323b565b806001600160a01b0316836001600160a01b03167f02508c98f5b30f12e216477136240f270c87a5992a7c6d5e0b8960a9f6f6af8984604051610da29190613f15565b60405180910390a3505050565b6000806000610df385858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061053592505050565b604051631293efbb60e21b81529091506001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690634a4fbeec90610e42908990600401613f15565b602060405180830381865afa158015610e5f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e8391906140f7565b15610f94576001600160e01b03198116630bdb124f60e21b1480610eb757506001600160e01b03198116630304e0bb60e41b145b80610ed257506001600160e01b0319811663e6c09edf60e01b145b610eee5760405162461bcd60e51b815260040161058190614136565b633424edb160e21b6001600160e01b0319821601610f94577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663e06902ea6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610f64573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f889190614166565b600392509250506115ea565b604051634f6c171d60e01b81526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690634f6c171d90610fe0908990600401613f15565b602060405180830381865afa158015610ffd573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061102191906140f7565b156110a7576001600160e01b03198116630304e0bb60e41b148061105557506001600160e01b0319811663a5efb23560e01b145b8061107057506001600160e01b031981166301d6991160e21b145b8061108b57506001600160e01b03198116632642a09360e11b145b6110a75760405162461bcd60e51b815260040161058190614136565b635a104dcb60e01b6001600160e01b031982160161128557604051633b325d3760e01b81526000906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690633b325d379061110e908a90600401613f15565b602060405180830381865afa15801561112b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061114f91906140f7565b9050806111ea57604051634a81d26d60e11b81526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690639503a4da906111a2908a90600401613f15565b602060405180830381865afa1580156111bf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111e39190614166565b600161127a565b604051634a81d26d60e11b81526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690639503a4da90611236908a90600401613f15565b602060405180830381865afa158015611253573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112779190614166565b60025b9350935050506115ea565b633e2966ef60e21b6001600160e01b031982160161135357604051633b325d3760e01b81526000906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690633b325d37906112ec908a90600401613f15565b602060405180830381865afa158015611309573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061132d91906140f7565b90508061133d5760006001611342565b600060025b8160ff1691509350935050506115ea565b630bca0a5960e01b6001600160e01b0319821601611379576000600492509250506115ea565b6001600160e01b03198116630d0ed3fb60e31b14806113a857506001600160e01b03198116631add82a560e21b145b806113c357506001600160e01b031981166319a145c760e01b145b1561146157604051634a81d26d60e11b81526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690639503a4da90611414908990600401613f15565b602060405180830381865afa158015611431573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114559190614166565b600192509250506115ea565b6001600160e01b031981166375033f4b60e01b148061149057506001600160e01b03198116630189028360e11b145b156114f3577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663c15d8b966040518163ffffffff1660e01b8152600401602060405180830381865afa158015611431573d6000803e3d6000fd5b6001600160e01b03198116638a85073b60e01b148061152257506001600160e01b03198116632b10673f60e21b145b8061153d57506001600160e01b031981166371bf3af160e01b145b15611550576000600192509250506115ea565b6001600160e01b03198116632642a09360e11b148061157f57506001600160e01b0319811663e6c09edf60e01b145b8061159a57506001600160e01b03198116630304e0bb60e41b145b156115ad576000600492509250506115ea565b60405162461bcd60e51b815260206004820152601260248201527112d34e881d5b9adb9bdddb881b595d1a1bd960721b6044820152606401610581565b935093915050565b6115fb33612f1f565b6116175760405162461bcd60e51b815260040161058190613f78565b604051632642a09360e11b81526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690634c854126906116659085908590600401613fa4565b600060405180830381600087803b15801561167f57600080fd5b505af1158015611693573d6000803e3d6000fd5b50505050816001600160a01b03167f2ef82a929ca200bcfdf95dec72ea691570ae7f78d47534fb8a60ca19da7c61f082604051610b309190613f15565b6040516000906116f490601960f81b9083908890889088904690899060200161417f565b60408051601f198184030181529082905280516020918201207f19457468657265756d205369676e6564204d6573736167653a0a33320000000091830191909152603c820152605c016040516020818303038152906040528051906020012090505b949350505050565b6001600160a01b0391909116600090815260208181526040808320938352600190930190522054151590565b61179333612f1f565b6117af5760405162461bcd60e51b815260040161058190613f78565b816001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156117ed573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118119190614119565b6001600160a01b0316816001600160a01b0316036118685760405162461bcd60e51b815260206004820152601460248201527329a69d1024b73b30b634b21033bab0b93234b0b760611b6044820152606401610581565b604051630d0ed3fb60e31b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906368769fd8906118b69085908590600401613fa4565b600060405180830381600087803b1580156118d057600080fd5b505af11580156118e4573d6000803e3d6000fd5b50506040516001600160a01b038085169350851691507f6e60a4dea8b0048bb934b375dde93967bc9163c35c0b9d5cfe0dc1f04e5e2d9e90600090a35050565b600060418351101561193857506000611756565b60006119468585600061308d565b9050600083600481111561195c5761195c613c3e565b036119df57856001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561199f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119c39190614119565b6001600160a01b0316816001600160a01b031614915050611756565b60028360048111156119f3576119f3613c3e565b03611a8e5760405162c7fe6f60e71b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906363ff378090611a459089908590600401613fa4565b602060405180830381865afa158015611a62573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a8691906140f7565b915050611756565b6001836004811115611aa257611aa2613c3e565b1480611abf57506003836004811115611abd57611abd613c3e565b145b15611c0257604184511115611bb4576000611adc8686600161308d565b60405163be546e0d60e01b81529091506001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063be546e0d90611b2d908a908690600401613fa4565b602060405180830381865afa158015611b4a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b6e91906140f7565b8015611bab57507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316816001600160a01b0316145b92505050611756565b60405163be546e0d60e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063be546e0d90611a459089908590600401613fa4565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316816001600160a01b031614915050949350505050565b611c4b33612f1f565b611c675760405162461bcd60e51b815260040161058190613f78565b611c7283838361323b565b826001600160a01b03167fab0ca8c1a4d3a9baa49449ec32c98bdc60c6e9ecec571ed15582b90dca7d9e298383604051611cad929190613fa4565b60405180910390a2505050565b6000611cc7878787613311565b611d135760405162461bcd60e51b815260206004820152601d60248201527f4b523a20546172676574206f66205f6461746120213d205f7661756c740000006044820152606401610581565b611d3d60408051608081019091528060008152600060208201819052604082015260609081015290565b6000611d4a898989610daf565b83816004811115611d5d57611d5d613c3e565b6004811115611d6e57611d6e613c3e565b8152508192505050611dba8960008a8a8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508c92506116d0915050565b60208301819052611dcc908a9061175e565b15611f4c576001600160a01b0389166000908152602081815260408083208583015184526001019091529020544211611e3e5760405162461bcd60e51b815260206004820152601460248201527312d48e88151a5b59481b9bdd08195e1c1a5c995960621b6044820152606401610581565b6040513090611e50908a908a906141e7565b6000604051808303816000865af19150503d8060008114611e8d576040519150601f19603f3d011682016040523d82523d6000602084013e611e92565b606091505b506060840152151560408301819052611ebd5760405162461bcd60e51b8152600401610581906141f7565b6001600160a01b03891660009081526020819052604090206003015415611eee57611eec8983602001516133db565b505b81604001511515896001600160a01b03167f7da4525a280527268ba2e963ee6c1b18f43c9507bcb1d2560f652ab17c76e90a84606001518560200151604051611f38929190614229565b60405180910390a35060400151905061215d565b611f9489836020015187878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050875191506119249050565b611fb05760405162461bcd60e51b81526004016105819061424b565b611fba89876134d2565b611ffe5760405162461bcd60e51b815260206004820152601560248201527412d48e88111d5c1b1a58d85d19481c995c5d595cdd605a1b6044820152606401610581565b80156120de576000612010824261427b565b6001600160a01b038b1660008181526020818152604080832088830180518552600180830185529285208790558585528484525160039091018054808401825581865293852090930155929091525491925061206b9161428e565b6001600160a01b038b1660008181526020818152604080832088830180518552600290910183529281902094909455905183518581529182015290917fa738aec4c92150604d027c7e038eb5f4889db730c1b895700442dad4b90ba665910160405180910390a26001935050505061215d565b60405130906120f0908a908a906141e7565b6000604051808303816000865af19150503d806000811461212d576040519150601f19603f3d011682016040523d82523d6000602084013e612132565b606091505b506060840152151560408301819052611eee5760405162461bcd60e51b8152600401610581906141f7565b9695505050505050565b61217033612f1f565b61218c5760405162461bcd60e51b815260040161058190613f78565b604051630bcd4ebb60e01b81526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690630bcd4ebb906121d8908590600401613f15565b602060405180830381865afa1580156121f5573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061221991906140f7565b6122655760405162461bcd60e51b815260206004820152601c60248201527f4b4d3a206d6f64756c65206973206e6f742072656769737465726564000000006044820152606401610581565b604051632411c8f960e21b81526001600160a01b0384169063904723e49061229690859060019086906004016142a1565b600060405180830381600087803b1580156122b057600080fd5b505af11580156122c4573d6000803e3d6000fd5b50505050505050565b6122d633612f1f565b6122f25760405162461bcd60e51b815260040161058190613f78565b604051630d0ed3fb60e31b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906368769fd890612341908490600090600401613fa4565b600060405180830381600087803b15801561235b57600080fd5b505af115801561236f573d6000803e3d6000fd5b5050604051600092506001600160a01b03841691507f6e60a4dea8b0048bb934b375dde93967bc9163c35c0b9d5cfe0dc1f04e5e2d9e908390a350565b6123b533612f1f565b6123d15760405162461bcd60e51b815260040161058190613f78565b604051632ad7108960e21b81526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063ab5c422490612420908690600401613f15565b602060405180830381865afa15801561243d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124619190614119565b6001600160a01b0316146118685760405162461bcd60e51b815260206004820152601760248201527629a69d1021b0b73737ba1030b2321033bab0b93234b0b760491b6044820152606401610581565b6124ba33612f1f565b6124d65760405162461bcd60e51b815260040161058190613f78565b6001600160a01b038116600090815260208190526040812060030154905b81811015612579576001600160a01b038316600090815260208190526040812060030180548390811061252957612529613fbe565b6000918252602080832091909101546001600160a01b038716835282825260408084209184526001820183528084208490556002909101909152812055508061257181614050565b9150506124f4565b506001600160a01b03821660009081526020819052604081206125a191600390910190613865565b6040516001600160a01b038316907fcb3a402591669c34ab2f5a32672eb79a626343ceea975d0b1be66ce67298e76f90600090a25050565b60606125e433612f1f565b6126005760405162461bcd60e51b815260040161058190613f78565b611756848484612f2d565b61261433612f1f565b6126305760405162461bcd60e51b815260040161058190613f78565b604051630435586b60e11b81526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063086ab0d69061267f908690600401613f15565b602060405180830381865afa15801561269c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126c09190614119565b6001600160a01b03161480156126de57506001600160a01b03811615155b6127235760405162461bcd60e51b8152602060048201526016602482015275534d3a2043616e6e6f7420616464207472757374656560501b6044820152606401610581565b60405163da209d5160e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063da209d51906127719085908590600401613fa4565b600060405180830381600087803b15801561278b57600080fd5b505af115801561279f573d6000803e3d6000fd5b50506040516001600160a01b038085169350851691507f313fbef49831f81de756df207bd6dd33dc4f5757ebd556a3375e05c1050c3aa490600090a35050565b82336001600160a01b038216146128335760405162461bcd60e51b815260206004820152601860248201527710934e8818d85b1b195c881b5d5cdd081899481d985d5b1d60421b6044820152606401610581565b60008061284284860186613a34565b91509150816001600160a01b0316866001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561288e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128b29190614119565b6001600160a01b0316036128fa5760405162461bcd60e51b815260206004820152600f60248201526e4b4d3a20496e76616c6964204b424760881b6044820152606401610581565b604051634a933b1f60e01b81526001600160a01b03871690634a933b1f90612926903090600401613f15565b600060405180830381600087803b15801561294057600080fd5b505af1158015612954573d6000803e3d6000fd5b50506040516319a145c760e01b81526001600160a01b038981166004830152602482018590527f00000000000000000000000000000000000000000000000000000000000000001692506319a145c79150604401600060405180830381600087803b1580156129c257600080fd5b505af11580156129d6573d6000803e3d6000fd5b5050604051634ff4b8e160e11b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169250639fe971c29150612a289089908690600401613fa4565b600060405180830381600087803b158015612a4257600080fd5b505af1158015612a56573d6000803e3d6000fd5b50505050505050505050565b6000612aa886600087878080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508992506116d0915050565b90506000612ad387600060405180604001604052806002815260200161060f60f31b815250876116d0565b9050612adf878361175e565b612b1e5760405162461bcd60e51b815260206004820152601060248201526f096a4744092dcecc2d8d2c840d0c2e6d60831b6044820152606401610581565b6000612b2a8787612bac565b9050612b3888838684611924565b612b545760405162461bcd60e51b81526004016105819061424b565b612b5e88846133db565b50876001600160a01b03167ff9303c741b41fde5495cd4aa8eb1ff8c2912281060edd43056567cce727d627784604051612b9a91815260200190565b60405180910390a25050505050505050565b600080612bee84848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061053592505050565b90506001600160e01b03198116630d0ed3fb60e31b1480612c1f57506001600160e01b031981166375033f4b60e01b145b80612c3a57506001600160e01b031981166319a145c760e01b145b80612c5557506001600160e01b03198116631add82a560e21b145b80612c7057506001600160e01b03198116630189028360e11b145b80612c8b57506001600160e01b0319811663a5efb23560e01b145b80612ca657506001600160e01b03198116630bdb124f60e21b145b156115ad5760009150506105c3565b612cbe33612f1f565b612cda5760405162461bcd60e51b815260040161058190613f78565b60405163e6c09edf60e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063e6c09edf90612d26908490600401613f15565b600060405180830381600087803b158015612d4057600080fd5b505af1158015612d54573d6000803e3d6000fd5b50506040516001600160a01b03841692507ff54453d15e2e6aee566733e6da03165ea58500408e802e05aa4e75f2408f59fe9150600090a250565b612d9833612f1f565b612db45760405162461bcd60e51b815260040161058190613f78565b60405163f435f5a760e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063f435f5a790612e00908490600401613f15565b600060405180830381600087803b158015612e1a57600080fd5b505af1158015612e2e573d6000803e3d6000fd5b505050506000306001600160a01b031682604051602401612e4f9190613f15565b60408051601f198184030181529181526020820180516001600160e01b03166397e8f71760e01b17905251612e8491906142d6565b6000604051808303816000865af19150503d8060008114612ec1576040519150601f19603f3d011682016040523d82523d6000602084013e612ec6565b606091505b5050905080612ee75760405162461bcd60e51b8152600401610581906142e8565b6040516001600160a01b038316907f44427e3003a08f22cf803894075ac0297524e09e521fc1c15bc91741ce3dc15990600090a25050565b6001600160a01b0316301490565b60606000826001600160401b03811115612f4957612f49613a60565b604051908082528060200260200182016040528015612f7c57816020015b6060815260200190600190039081612f675790505b50905060005b838110156130845761305486868684818110612fa057612fa0613fbe565b9050602002810190612fb29190613fd4565b612fc09060208101906138de565b878785818110612fd257612fd2613fbe565b9050602002810190612fe49190613fd4565b60200135888886818110612ffa57612ffa613fbe565b905060200281019061300c9190613fd4565b61301a906040810190613ff4565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061353d92505050565b82828151811061306657613066613fbe565b6020026020010181905250808061307c90614050565b915050612f82565b50949350505050565b6041808202830160208101516040820151919092015160009260ff9190911691601b8314806130bf57508260ff16601c145b61310b5760405162461bcd60e51b815260206004820152601b60248201527f553a2062616420762076616c756520696e207369676e617475726500000000006044820152606401610581565b604080516000808252602082018084528a905260ff861692820192909252606081018490526080810183905260019060a0016020604051602081039080840390855afa15801561315f573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811661096a5760405162461bcd60e51b81526020600482015260176024820152760553a2065637265636f7665722072657475726e6564203604c1b6044820152606401610581565b6000816001600160a01b0316836001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613206573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061322a9190614119565b6001600160a01b0316149392505050565b6132458383613664565b604051636b8ab97d60e01b81526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690636b8ab97d90613291908690600401613f15565b600060405180830381600087803b1580156132ab57600080fd5b505af11580156132bf573d6000803e3d6000fd5b5050604051634ff4b8e160e11b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169250639fe971c291506122969086908590600401613fa4565b6000602482101561335c5760405162461bcd60e51b815260206004820152601560248201527412d48e88125b9d985b1a590819185d1855985d5b1d605a1b6044820152606401610581565b6001600160a01b0384166133a65760405162461bcd60e51b815260206004820152601160248201527012d48e88125b9d985b1a59081d985d5b1d607a1b6044820152606401610581565b60006133b5836004818761431f565b8101906133c291906138de565b6001600160a01b03908116908616149150509392505050565b6001600160a01b03821660009081526020818152604080832084845260018082018452828520859055600282019093529083205460038201549192909190613423908261428e565b821461349c5760006003840161343a60018461428e565b8154811061344a5761344a613fbe565b600091825260208083209091015480835260028701909152604080832086905588835282209190915560038501805491925082918590811061348e5761348e613fbe565b600091825260209091200155505b826003018054806134af576134af614349565b600190038181906000526020600020016000905590556001935050505092915050565b6001600160a01b03821660009081526020819052604081205482116134f9575060006105c3565b608082901c61350a6127104361427b565b81111561351b5760009150506105c3565b50506001600160a01b0391909116600090815260208190526040902055600190565b60606000856001600160a01b03168585856040516024016135609392919061435f565b60408051601f198184030181529181526020820180516001600160e01b03166347b7819960e11b1790525161359591906142d6565b6000604051808303816000865af19150503d80600081146135d2576040519150601f19603f3d011682016040523d82523d6000602084013e6135d7565b606091505b50925090508080156135ea575060008251115b1561360a57818060200190518101906136039190614386565b9150613084565b81511561361b573d6000803e3d6000fd5b806130845760405162461bcd60e51b815260206004820152601960248201527810934e881d985d5b1d081a5b9d9bdad9481c995d995c9d1959603a1b6044820152606401610581565b61366e8282613786565b6040516313af403560e01b81526001600160a01b038316906313af40359061369a908490600401613f15565b600060405180830381600087803b1580156136b457600080fd5b505af11580156136c8573d6000803e3d6000fd5b505050506000306001600160a01b0316836040516024016136e99190613f15565b60408051601f198184030181529181526020820180516001600160e01b03166397e8f71760e01b1790525161371e91906142d6565b6000604051808303816000865af19150503d806000811461375b576040519150601f19603f3d011682016040523d82523d6000602084013e613760565b606091505b50509050806137815760405162461bcd60e51b8152600401610581906142e8565b505050565b60405162c7fe6f60e71b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906363ff3780906137d39085908590600401613fa4565b602060405180830381865afa1580156137f0573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061381491906140f7565b156138615760405162461bcd60e51b815260206004820181905260248201527f534d3a206e6577206f776e65722063616e6e6f7420626520677561726469616e6044820152606401610581565b5050565b50805460008255906000526020600020908101906138839190613886565b50565b5b8082111561389b5760008155600101613887565b5090565b6000602082840312156138b157600080fd5b81356001600160e01b03198116811461097057600080fd5b6001600160a01b038116811461388357600080fd5b6000602082840312156138f057600080fd5b8135610970816138c9565b60008060006040848603121561391057600080fd5b833561391b816138c9565b925060208401356001600160401b038082111561393757600080fd5b818601915086601f83011261394b57600080fd5b81358181111561395a57600080fd5b8760208260051b850101111561396f57600080fd5b6020830194508093505050509250925092565b60005b8381101561399d578181015183820152602001613985565b50506000910152565b600081518084526139be816020860160208601613982565b601f01601f19169290920160200192915050565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b82811015613a2757603f19888603018452613a158583516139a6565b945092850192908501906001016139f9565b5092979650505050505050565b60008060408385031215613a4757600080fd5b8235613a52816138c9565b946020939093013593505050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b0381118282101715613a9e57613a9e613a60565b604052919050565b60006001600160401b03821115613abf57613abf613a60565b50601f01601f191660200190565b600082601f830112613ade57600080fd5b8135613af1613aec82613aa6565b613a76565b818152846020838601011115613b0657600080fd5b816020850160208301376000918101602001919091529392505050565b60008060408385031215613b3657600080fd5b8235915060208301356001600160401b03811115613b5357600080fd5b613b5f85828601613acd565b9150509250929050565b60008060408385031215613b7c57600080fd5b8235613b87816138c9565b91506020830135613b97816138c9565b809150509250929050565b60008083601f840112613bb457600080fd5b5081356001600160401b03811115613bcb57600080fd5b602083019150836020828501011115613be357600080fd5b9250929050565b600080600060408486031215613bff57600080fd5b8335613c0a816138c9565b925060208401356001600160401b03811115613c2557600080fd5b613c3186828701613ba2565b9497909650939450505050565b634e487b7160e01b600052602160045260246000fd5b60058110613c7257634e487b7160e01b600052602160045260246000fd5b9052565b828152604081016109706020830184613c54565b60008060008060808587031215613ca057600080fd5b8435613cab816138c9565b93506020850135925060408501356001600160401b03811115613ccd57600080fd5b613cd987828801613acd565b949793965093946060013593505050565b60008060008060808587031215613d0057600080fd5b8435613d0b816138c9565b93506020850135925060408501356001600160401b03811115613d2d57600080fd5b613d3987828801613acd565b925050606085013560058110613d4e57600080fd5b939692955090935050565b600080600060608486031215613d6e57600080fd5b8335613d79816138c9565b92506020840135613d89816138c9565b91506040840135613d99816138c9565b809150509250925092565b60008060008060008060808789031215613dbd57600080fd5b8635613dc8816138c9565b955060208701356001600160401b0380821115613de457600080fd5b613df08a838b01613ba2565b9097509550604089013594506060890135915080821115613e1057600080fd5b50613e1d89828a01613ba2565b979a9699509497509295939492505050565b600080600060608486031215613e4457600080fd5b8335613e4f816138c9565b92506020840135613e5f816138c9565b915060408401356001600160401b03811115613e7a57600080fd5b613e8686828701613acd565b9150509250925092565b600080600080600060808688031215613ea857600080fd5b8535613eb3816138c9565b945060208601356001600160401b0380821115613ecf57600080fd5b613edb89838a01613ba2565b9096509450604088013593506060880135915080821115613efb57600080fd5b50613f0888828901613acd565b9150509295509295909350565b6001600160a01b0391909116815260200190565b60008060208385031215613f3c57600080fd5b82356001600160401b03811115613f5257600080fd5b613f5e85828601613ba2565b90969095509350505050565b602081016105c38284613c54565b602080825260129082015271424d3a206d757374206265206d6f64756c6560701b604082015260600190565b6001600160a01b0392831681529116602082015260400190565b634e487b7160e01b600052603260045260246000fd5b60008235605e19833603018112613fea57600080fd5b9190910192915050565b6000808335601e1984360301811261400b57600080fd5b8301803591506001600160401b0382111561402557600080fd5b602001915036819003821315613be357600080fd5b634e487b7160e01b600052601160045260246000fd5b6000600182016140625761406261403a565b5060010190565b604080825283519082018190526000906020906060840190828701845b828110156140ab5781516001600160a01b031684529284019290840190600101614086565b5050508381038285015284518082528583019183019060005b818110156140ea5783516001600160e01b031916835292840192918401916001016140c4565b5090979650505050505050565b60006020828403121561410957600080fd5b8151801515811461097057600080fd5b60006020828403121561412b57600080fd5b8151610970816138c9565b60208082526016908201527512d34e881b595d1a1bd9081b9bdd08185b1b1bddd95960521b604082015260600190565b60006020828403121561417857600080fd5b5051919050565b6001600160f81b0319888116825287166001820152606086901b6bffffffffffffffffffffffff191660028201526016810185905283516000906141ca816036850160208901613982565b909101603681019390935250605682015260760195945050505050565b8183823760009101908152919050565b60208082526018908201527712d48e88125b9d195c9b985b0818d85b1b0819985a5b195960421b604082015260600190565b60408152600061423c60408301856139a6565b90508260208301529392505050565b6020808252601690820152754b523a20496e76616c6964205369676e61747572657360501b604082015260600190565b808201808211156105c3576105c361403a565b818103818111156105c3576105c361403a565b6001600160a01b038416815282151560208201526060604082018190526000906142cd908301846139a6565b95945050505050565b60008251613fea818460208701613982565b6020808252601f908201527f534d3a2063616e63656c20616c6c206f7065726174696f6e206661696c656400604082015260600190565b6000808585111561432f57600080fd5b8386111561433c57600080fd5b5050820193919092039150565b634e487b7160e01b600052603160045260246000fd5b60018060a01b03841681528260208201526060604082015260006142cd60608301846139a6565b60006020828403121561439857600080fd5b81516001600160401b038111156143ae57600080fd5b8201601f810184136143bf57600080fd5b80516143cd613aec82613aa6565b8181528560208385010111156143e257600080fd5b6142cd82602083016020860161398256fea26469706673582212200b45be967ad1fe1cde69d34b9573a79a5b374c9e03b730b17f8d73d4fb90282664736f6c634300081100330000000000000000000000003712d49bed8335d3b90c34109a48d9cd5ee8daaf00000000000000000000000083c2defd5bb812b5b15f28f2b9534a3c70481bc10000000000000000000000007bf09a75da7e88977150f452135ead9c90729cbd

Deployed Bytecode

0x608060405234801561001057600080fd5b506004361061019a5760003560e01c8063694c596b116100e4578063a5efb23511610092578063a5efb2351461046f578063ac419cfc14610482578063c0d91eaf14610495578063c10cab45146104a8578063cbb98bee146104bb578063ce1d3e2f146104ef578063e6c09edf1461050f578063f435f5a7146105225761019a565b8063694c596b146103ea5780636b760a94146103fd5780636c459a281461041057806371bf3af11461042357806375033f4b146104365780638a85073b1461044957806397e8f7171461045c5761019a565b80632d0335ab1161014c5780632d0335ab1461032e5780632f6c493c14610357578063304e0bb01461036a5780633b73d67f1461037d5780634c8541261461039e5780635ad5f3e4146103b15780635d80f160146103c457806368769fd8146103d75761019a565b806301ffc9a71461023b5780630312050614610263578063075a6444146102765780630a6dd219146102965780631626ba7e146102dc57806319a145c71461030857806325b509341461031b575b60006101dc6000368080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061053592505050565b90506001600160e01b03198116630a85bd0160e11b148061020d57506001600160e01b0319811663f23a6e6160e01b145b8061022857506001600160e01b0319811663bc197c8160e01b145b156102395760046000803760206000f35b005b61024e61024936600461389f565b610592565b60405190151581526020015b60405180910390f35b6102396102713660046138de565b6105c9565b6102896102843660046138fb565b6106a8565b60405161025a91906139d2565b6102ce6102a4366004613a34565b6001600160a01b039190911660009081526020818152604080832093835260019093019052205490565b60405190815260200161025a565b6102ef6102ea366004613b23565b610977565b6040516001600160e01b0319909116815260200161025a565b610239610316366004613a34565b610a4e565b61024e61032936600461389f565b610b3c565b6102ce61033c3660046138de565b6001600160a01b031660009081526020819052604090205490565b6102396103653660046138de565b610bc3565b610239610378366004613b69565b610c9d565b61039061038b366004613bea565b610daf565b60405161025a929190613c76565b6102396103ac366004613b69565b6115f2565b6102ce6103bf366004613c8a565b6116d0565b61024e6103d2366004613a34565b61175e565b6102396103e5366004613b69565b61178a565b61024e6103f8366004613cea565b611924565b61023961040b366004613d59565b611c42565b61024e61041e366004613da4565b611cba565b610239610431366004613e2f565b612167565b6102396104443660046138de565b6122cd565b610239610457366004613b69565b6123ac565b61023961046a3660046138de565b6124b1565b61028961047d3660046138fb565b6125d9565b610239610490366004613b69565b61260b565b6102396104a3366004613bea565b6127df565b6102396104b6366004613e90565b612a62565b6104e27f0000000000000000000000007bf09a75da7e88977150f452135ead9c90729cbd81565b60405161025a9190613f15565b6105026104fd366004613f29565b612bac565b60405161025a9190613f6a565b61023961051d3660046138de565b612cb5565b6102396105303660046138de565b612d8f565b600060048251101561058a5760405162461bcd60e51b81526020600482015260196024820152780aa744092dcecc2d8d2c840cceadcc6e8d2dedca0e4caccd2f603b1b60448201526064015b60405180910390fd5b506020015190565b60006001600160e01b031982166301ffc9a760e01b14806105c357506001600160e01b03198216630271189760e51b145b92915050565b6105d233612f1f565b6105ee5760405162461bcd60e51b815260040161058190613f78565b60405163da209d5160e01b81526001600160a01b037f0000000000000000000000003712d49bed8335d3b90c34109a48d9cd5ee8daaf169063da209d519061063d908490600090600401613fa4565b600060405180830381600087803b15801561065757600080fd5b505af115801561066b573d6000803e3d6000fd5b5050604051600092506001600160a01b03841691507f313fbef49831f81de756df207bd6dd33dc4f5757ebd556a3375e05c1050c3aa4908390a350565b60606106b333612f1f565b6106cf5760405162461bcd60e51b815260040161058190613f78565b816000816001600160401b038111156106ea576106ea613a60565b604051908082528060200260200182016040528015610713578160200160208202803683370190505b5090506000826001600160401b0381111561073057610730613a60565b604051908082528060200260200182016040528015610759578160200160208202803683370190505b50905060005b838110156108775786868281811061077957610779613fbe565b905060200281019061078b9190613fd4565b6107999060208101906138de565b8382815181106107ab576107ab613fbe565b60200260200101906001600160a01b031690816001600160a01b03168152505061083a8787838181106107e0576107e0613fbe565b90506020028101906107f29190613fd4565b610800906040810190613ff4565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061053592505050565b82828151811061084c5761084c613fbe565b6001600160e01b0319909216602092830291909101909101528061086f81614050565b91505061075f565b50604051634ab00efb60e01b81526001600160a01b037f00000000000000000000000083c2defd5bb812b5b15f28f2b9534a3c70481bc11690634ab00efb906108c69085908590600401614069565b602060405180830381865afa1580156108e3573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061090791906140f7565b61095f5760405162461bcd60e51b8152602060048201526024808201527f544d3a20416464726573736573206f722053696773206e6f7420726567697374604482015263195c995960e21b6064820152608401610581565b61096a878787612f2d565b93505050505b9392505050565b600081516041146109ca5760405162461bcd60e51b815260206004820152601c60248201527f544d3a20696e76616c6964207369676e6174757265206c656e677468000000006044820152606401610581565b60006109d88484600061308d565b90506109e433826131bc565b610a255760405162461bcd60e51b81526020600482015260126024820152712a269d1024b73b30b634b21039b4b3b732b960711b6044820152606401610581565b507f1626ba7e356f5979dd355a3d2bfb43e80420a480c3b854edce286a82d74968699392505050565b610a5733612f1f565b610a735760405162461bcd60e51b815260040161058190613f78565b6040516319a145c760e01b81526001600160a01b038381166004830152602482018390527f0000000000000000000000003712d49bed8335d3b90c34109a48d9cd5ee8daaf16906319a145c790604401600060405180830381600087803b158015610add57600080fd5b505af1158015610af1573d6000803e3d6000fd5b50505050816001600160a01b03167fcbe22d4428901024069c2997f8626afe4fe1a1e280a8de9618d51351b9b265b782604051610b3091815260200190565b60405180910390a25050565b60006001600160e01b03198216630b135d3f60e11b1480610b6d57506001600160e01b03198216630a85bd0160e11b145b80610b8857506001600160e01b031982166301ffc9a760e01b145b80610ba357506001600160e01b0319821663f23a6e6160e01b145b806105c357506001600160e01b0319821663bc197c8160e01b1492915050565b610bcc33612f1f565b610be85760405162461bcd60e51b815260040161058190613f78565b604051630bdb124f60e21b81526001600160a01b037f0000000000000000000000003712d49bed8335d3b90c34109a48d9cd5ee8daaf1690632f6c493c90610c34908490600401613f15565b600060405180830381600087803b158015610c4e57600080fd5b505af1158015610c62573d6000803e3d6000fd5b50506040516001600160a01b03841692507f7e6adfec7e3f286831a0200a754127c171a2da564078722cb97704741bbdb0ea9150600090a250565b610ca633612f1f565b610cc25760405162461bcd60e51b815260040161058190613f78565b604051630435586b60e11b81526000906001600160a01b037f0000000000000000000000003712d49bed8335d3b90c34109a48d9cd5ee8daaf169063086ab0d690610d11908690600401613f15565b602060405180830381865afa158015610d2e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d529190614119565b9050610d5f83828461323b565b806001600160a01b0316836001600160a01b03167f02508c98f5b30f12e216477136240f270c87a5992a7c6d5e0b8960a9f6f6af8984604051610da29190613f15565b60405180910390a3505050565b6000806000610df385858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061053592505050565b604051631293efbb60e21b81529091506001600160a01b037f0000000000000000000000003712d49bed8335d3b90c34109a48d9cd5ee8daaf1690634a4fbeec90610e42908990600401613f15565b602060405180830381865afa158015610e5f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e8391906140f7565b15610f94576001600160e01b03198116630bdb124f60e21b1480610eb757506001600160e01b03198116630304e0bb60e41b145b80610ed257506001600160e01b0319811663e6c09edf60e01b145b610eee5760405162461bcd60e51b815260040161058190614136565b633424edb160e21b6001600160e01b0319821601610f94577f00000000000000000000000083c2defd5bb812b5b15f28f2b9534a3c70481bc16001600160a01b031663e06902ea6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610f64573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f889190614166565b600392509250506115ea565b604051634f6c171d60e01b81526001600160a01b037f0000000000000000000000003712d49bed8335d3b90c34109a48d9cd5ee8daaf1690634f6c171d90610fe0908990600401613f15565b602060405180830381865afa158015610ffd573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061102191906140f7565b156110a7576001600160e01b03198116630304e0bb60e41b148061105557506001600160e01b0319811663a5efb23560e01b145b8061107057506001600160e01b031981166301d6991160e21b145b8061108b57506001600160e01b03198116632642a09360e11b145b6110a75760405162461bcd60e51b815260040161058190614136565b635a104dcb60e01b6001600160e01b031982160161128557604051633b325d3760e01b81526000906001600160a01b037f0000000000000000000000003712d49bed8335d3b90c34109a48d9cd5ee8daaf1690633b325d379061110e908a90600401613f15565b602060405180830381865afa15801561112b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061114f91906140f7565b9050806111ea57604051634a81d26d60e11b81526001600160a01b037f0000000000000000000000003712d49bed8335d3b90c34109a48d9cd5ee8daaf1690639503a4da906111a2908a90600401613f15565b602060405180830381865afa1580156111bf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111e39190614166565b600161127a565b604051634a81d26d60e11b81526001600160a01b037f0000000000000000000000003712d49bed8335d3b90c34109a48d9cd5ee8daaf1690639503a4da90611236908a90600401613f15565b602060405180830381865afa158015611253573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112779190614166565b60025b9350935050506115ea565b633e2966ef60e21b6001600160e01b031982160161135357604051633b325d3760e01b81526000906001600160a01b037f0000000000000000000000003712d49bed8335d3b90c34109a48d9cd5ee8daaf1690633b325d37906112ec908a90600401613f15565b602060405180830381865afa158015611309573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061132d91906140f7565b90508061133d5760006001611342565b600060025b8160ff1691509350935050506115ea565b630bca0a5960e01b6001600160e01b0319821601611379576000600492509250506115ea565b6001600160e01b03198116630d0ed3fb60e31b14806113a857506001600160e01b03198116631add82a560e21b145b806113c357506001600160e01b031981166319a145c760e01b145b1561146157604051634a81d26d60e11b81526001600160a01b037f0000000000000000000000003712d49bed8335d3b90c34109a48d9cd5ee8daaf1690639503a4da90611414908990600401613f15565b602060405180830381865afa158015611431573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114559190614166565b600192509250506115ea565b6001600160e01b031981166375033f4b60e01b148061149057506001600160e01b03198116630189028360e11b145b156114f3577f00000000000000000000000083c2defd5bb812b5b15f28f2b9534a3c70481bc16001600160a01b031663c15d8b966040518163ffffffff1660e01b8152600401602060405180830381865afa158015611431573d6000803e3d6000fd5b6001600160e01b03198116638a85073b60e01b148061152257506001600160e01b03198116632b10673f60e21b145b8061153d57506001600160e01b031981166371bf3af160e01b145b15611550576000600192509250506115ea565b6001600160e01b03198116632642a09360e11b148061157f57506001600160e01b0319811663e6c09edf60e01b145b8061159a57506001600160e01b03198116630304e0bb60e41b145b156115ad576000600492509250506115ea565b60405162461bcd60e51b815260206004820152601260248201527112d34e881d5b9adb9bdddb881b595d1a1bd960721b6044820152606401610581565b935093915050565b6115fb33612f1f565b6116175760405162461bcd60e51b815260040161058190613f78565b604051632642a09360e11b81526001600160a01b037f0000000000000000000000003712d49bed8335d3b90c34109a48d9cd5ee8daaf1690634c854126906116659085908590600401613fa4565b600060405180830381600087803b15801561167f57600080fd5b505af1158015611693573d6000803e3d6000fd5b50505050816001600160a01b03167f2ef82a929ca200bcfdf95dec72ea691570ae7f78d47534fb8a60ca19da7c61f082604051610b309190613f15565b6040516000906116f490601960f81b9083908890889088904690899060200161417f565b60408051601f198184030181529082905280516020918201207f19457468657265756d205369676e6564204d6573736167653a0a33320000000091830191909152603c820152605c016040516020818303038152906040528051906020012090505b949350505050565b6001600160a01b0391909116600090815260208181526040808320938352600190930190522054151590565b61179333612f1f565b6117af5760405162461bcd60e51b815260040161058190613f78565b816001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156117ed573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118119190614119565b6001600160a01b0316816001600160a01b0316036118685760405162461bcd60e51b815260206004820152601460248201527329a69d1024b73b30b634b21033bab0b93234b0b760611b6044820152606401610581565b604051630d0ed3fb60e31b81526001600160a01b037f0000000000000000000000003712d49bed8335d3b90c34109a48d9cd5ee8daaf16906368769fd8906118b69085908590600401613fa4565b600060405180830381600087803b1580156118d057600080fd5b505af11580156118e4573d6000803e3d6000fd5b50506040516001600160a01b038085169350851691507f6e60a4dea8b0048bb934b375dde93967bc9163c35c0b9d5cfe0dc1f04e5e2d9e90600090a35050565b600060418351101561193857506000611756565b60006119468585600061308d565b9050600083600481111561195c5761195c613c3e565b036119df57856001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561199f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119c39190614119565b6001600160a01b0316816001600160a01b031614915050611756565b60028360048111156119f3576119f3613c3e565b03611a8e5760405162c7fe6f60e71b81526001600160a01b037f0000000000000000000000003712d49bed8335d3b90c34109a48d9cd5ee8daaf16906363ff378090611a459089908590600401613fa4565b602060405180830381865afa158015611a62573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a8691906140f7565b915050611756565b6001836004811115611aa257611aa2613c3e565b1480611abf57506003836004811115611abd57611abd613c3e565b145b15611c0257604184511115611bb4576000611adc8686600161308d565b60405163be546e0d60e01b81529091506001600160a01b037f0000000000000000000000003712d49bed8335d3b90c34109a48d9cd5ee8daaf169063be546e0d90611b2d908a908690600401613fa4565b602060405180830381865afa158015611b4a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b6e91906140f7565b8015611bab57507f0000000000000000000000007bf09a75da7e88977150f452135ead9c90729cbd6001600160a01b0316816001600160a01b0316145b92505050611756565b60405163be546e0d60e01b81526001600160a01b037f0000000000000000000000003712d49bed8335d3b90c34109a48d9cd5ee8daaf169063be546e0d90611a459089908590600401613fa4565b7f0000000000000000000000007bf09a75da7e88977150f452135ead9c90729cbd6001600160a01b0316816001600160a01b031614915050949350505050565b611c4b33612f1f565b611c675760405162461bcd60e51b815260040161058190613f78565b611c7283838361323b565b826001600160a01b03167fab0ca8c1a4d3a9baa49449ec32c98bdc60c6e9ecec571ed15582b90dca7d9e298383604051611cad929190613fa4565b60405180910390a2505050565b6000611cc7878787613311565b611d135760405162461bcd60e51b815260206004820152601d60248201527f4b523a20546172676574206f66205f6461746120213d205f7661756c740000006044820152606401610581565b611d3d60408051608081019091528060008152600060208201819052604082015260609081015290565b6000611d4a898989610daf565b83816004811115611d5d57611d5d613c3e565b6004811115611d6e57611d6e613c3e565b8152508192505050611dba8960008a8a8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508c92506116d0915050565b60208301819052611dcc908a9061175e565b15611f4c576001600160a01b0389166000908152602081815260408083208583015184526001019091529020544211611e3e5760405162461bcd60e51b815260206004820152601460248201527312d48e88151a5b59481b9bdd08195e1c1a5c995960621b6044820152606401610581565b6040513090611e50908a908a906141e7565b6000604051808303816000865af19150503d8060008114611e8d576040519150601f19603f3d011682016040523d82523d6000602084013e611e92565b606091505b506060840152151560408301819052611ebd5760405162461bcd60e51b8152600401610581906141f7565b6001600160a01b03891660009081526020819052604090206003015415611eee57611eec8983602001516133db565b505b81604001511515896001600160a01b03167f7da4525a280527268ba2e963ee6c1b18f43c9507bcb1d2560f652ab17c76e90a84606001518560200151604051611f38929190614229565b60405180910390a35060400151905061215d565b611f9489836020015187878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050875191506119249050565b611fb05760405162461bcd60e51b81526004016105819061424b565b611fba89876134d2565b611ffe5760405162461bcd60e51b815260206004820152601560248201527412d48e88111d5c1b1a58d85d19481c995c5d595cdd605a1b6044820152606401610581565b80156120de576000612010824261427b565b6001600160a01b038b1660008181526020818152604080832088830180518552600180830185529285208790558585528484525160039091018054808401825581865293852090930155929091525491925061206b9161428e565b6001600160a01b038b1660008181526020818152604080832088830180518552600290910183529281902094909455905183518581529182015290917fa738aec4c92150604d027c7e038eb5f4889db730c1b895700442dad4b90ba665910160405180910390a26001935050505061215d565b60405130906120f0908a908a906141e7565b6000604051808303816000865af19150503d806000811461212d576040519150601f19603f3d011682016040523d82523d6000602084013e612132565b606091505b506060840152151560408301819052611eee5760405162461bcd60e51b8152600401610581906141f7565b9695505050505050565b61217033612f1f565b61218c5760405162461bcd60e51b815260040161058190613f78565b604051630bcd4ebb60e01b81526001600160a01b037f00000000000000000000000083c2defd5bb812b5b15f28f2b9534a3c70481bc11690630bcd4ebb906121d8908590600401613f15565b602060405180830381865afa1580156121f5573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061221991906140f7565b6122655760405162461bcd60e51b815260206004820152601c60248201527f4b4d3a206d6f64756c65206973206e6f742072656769737465726564000000006044820152606401610581565b604051632411c8f960e21b81526001600160a01b0384169063904723e49061229690859060019086906004016142a1565b600060405180830381600087803b1580156122b057600080fd5b505af11580156122c4573d6000803e3d6000fd5b50505050505050565b6122d633612f1f565b6122f25760405162461bcd60e51b815260040161058190613f78565b604051630d0ed3fb60e31b81526001600160a01b037f0000000000000000000000003712d49bed8335d3b90c34109a48d9cd5ee8daaf16906368769fd890612341908490600090600401613fa4565b600060405180830381600087803b15801561235b57600080fd5b505af115801561236f573d6000803e3d6000fd5b5050604051600092506001600160a01b03841691507f6e60a4dea8b0048bb934b375dde93967bc9163c35c0b9d5cfe0dc1f04e5e2d9e908390a350565b6123b533612f1f565b6123d15760405162461bcd60e51b815260040161058190613f78565b604051632ad7108960e21b81526000907f0000000000000000000000003712d49bed8335d3b90c34109a48d9cd5ee8daaf6001600160a01b03169063ab5c422490612420908690600401613f15565b602060405180830381865afa15801561243d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124619190614119565b6001600160a01b0316146118685760405162461bcd60e51b815260206004820152601760248201527629a69d1021b0b73737ba1030b2321033bab0b93234b0b760491b6044820152606401610581565b6124ba33612f1f565b6124d65760405162461bcd60e51b815260040161058190613f78565b6001600160a01b038116600090815260208190526040812060030154905b81811015612579576001600160a01b038316600090815260208190526040812060030180548390811061252957612529613fbe565b6000918252602080832091909101546001600160a01b038716835282825260408084209184526001820183528084208490556002909101909152812055508061257181614050565b9150506124f4565b506001600160a01b03821660009081526020819052604081206125a191600390910190613865565b6040516001600160a01b038316907fcb3a402591669c34ab2f5a32672eb79a626343ceea975d0b1be66ce67298e76f90600090a25050565b60606125e433612f1f565b6126005760405162461bcd60e51b815260040161058190613f78565b611756848484612f2d565b61261433612f1f565b6126305760405162461bcd60e51b815260040161058190613f78565b604051630435586b60e11b81526000907f0000000000000000000000003712d49bed8335d3b90c34109a48d9cd5ee8daaf6001600160a01b03169063086ab0d69061267f908690600401613f15565b602060405180830381865afa15801561269c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126c09190614119565b6001600160a01b03161480156126de57506001600160a01b03811615155b6127235760405162461bcd60e51b8152602060048201526016602482015275534d3a2043616e6e6f7420616464207472757374656560501b6044820152606401610581565b60405163da209d5160e01b81526001600160a01b037f0000000000000000000000003712d49bed8335d3b90c34109a48d9cd5ee8daaf169063da209d51906127719085908590600401613fa4565b600060405180830381600087803b15801561278b57600080fd5b505af115801561279f573d6000803e3d6000fd5b50506040516001600160a01b038085169350851691507f313fbef49831f81de756df207bd6dd33dc4f5757ebd556a3375e05c1050c3aa490600090a35050565b82336001600160a01b038216146128335760405162461bcd60e51b815260206004820152601860248201527710934e8818d85b1b195c881b5d5cdd081899481d985d5b1d60421b6044820152606401610581565b60008061284284860186613a34565b91509150816001600160a01b0316866001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561288e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128b29190614119565b6001600160a01b0316036128fa5760405162461bcd60e51b815260206004820152600f60248201526e4b4d3a20496e76616c6964204b424760881b6044820152606401610581565b604051634a933b1f60e01b81526001600160a01b03871690634a933b1f90612926903090600401613f15565b600060405180830381600087803b15801561294057600080fd5b505af1158015612954573d6000803e3d6000fd5b50506040516319a145c760e01b81526001600160a01b038981166004830152602482018590527f0000000000000000000000003712d49bed8335d3b90c34109a48d9cd5ee8daaf1692506319a145c79150604401600060405180830381600087803b1580156129c257600080fd5b505af11580156129d6573d6000803e3d6000fd5b5050604051634ff4b8e160e11b81526001600160a01b037f0000000000000000000000003712d49bed8335d3b90c34109a48d9cd5ee8daaf169250639fe971c29150612a289089908690600401613fa4565b600060405180830381600087803b158015612a4257600080fd5b505af1158015612a56573d6000803e3d6000fd5b50505050505050505050565b6000612aa886600087878080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508992506116d0915050565b90506000612ad387600060405180604001604052806002815260200161060f60f31b815250876116d0565b9050612adf878361175e565b612b1e5760405162461bcd60e51b815260206004820152601060248201526f096a4744092dcecc2d8d2c840d0c2e6d60831b6044820152606401610581565b6000612b2a8787612bac565b9050612b3888838684611924565b612b545760405162461bcd60e51b81526004016105819061424b565b612b5e88846133db565b50876001600160a01b03167ff9303c741b41fde5495cd4aa8eb1ff8c2912281060edd43056567cce727d627784604051612b9a91815260200190565b60405180910390a25050505050505050565b600080612bee84848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061053592505050565b90506001600160e01b03198116630d0ed3fb60e31b1480612c1f57506001600160e01b031981166375033f4b60e01b145b80612c3a57506001600160e01b031981166319a145c760e01b145b80612c5557506001600160e01b03198116631add82a560e21b145b80612c7057506001600160e01b03198116630189028360e11b145b80612c8b57506001600160e01b0319811663a5efb23560e01b145b80612ca657506001600160e01b03198116630bdb124f60e21b145b156115ad5760009150506105c3565b612cbe33612f1f565b612cda5760405162461bcd60e51b815260040161058190613f78565b60405163e6c09edf60e01b81526001600160a01b037f0000000000000000000000003712d49bed8335d3b90c34109a48d9cd5ee8daaf169063e6c09edf90612d26908490600401613f15565b600060405180830381600087803b158015612d4057600080fd5b505af1158015612d54573d6000803e3d6000fd5b50506040516001600160a01b03841692507ff54453d15e2e6aee566733e6da03165ea58500408e802e05aa4e75f2408f59fe9150600090a250565b612d9833612f1f565b612db45760405162461bcd60e51b815260040161058190613f78565b60405163f435f5a760e01b81526001600160a01b037f0000000000000000000000003712d49bed8335d3b90c34109a48d9cd5ee8daaf169063f435f5a790612e00908490600401613f15565b600060405180830381600087803b158015612e1a57600080fd5b505af1158015612e2e573d6000803e3d6000fd5b505050506000306001600160a01b031682604051602401612e4f9190613f15565b60408051601f198184030181529181526020820180516001600160e01b03166397e8f71760e01b17905251612e8491906142d6565b6000604051808303816000865af19150503d8060008114612ec1576040519150601f19603f3d011682016040523d82523d6000602084013e612ec6565b606091505b5050905080612ee75760405162461bcd60e51b8152600401610581906142e8565b6040516001600160a01b038316907f44427e3003a08f22cf803894075ac0297524e09e521fc1c15bc91741ce3dc15990600090a25050565b6001600160a01b0316301490565b60606000826001600160401b03811115612f4957612f49613a60565b604051908082528060200260200182016040528015612f7c57816020015b6060815260200190600190039081612f675790505b50905060005b838110156130845761305486868684818110612fa057612fa0613fbe565b9050602002810190612fb29190613fd4565b612fc09060208101906138de565b878785818110612fd257612fd2613fbe565b9050602002810190612fe49190613fd4565b60200135888886818110612ffa57612ffa613fbe565b905060200281019061300c9190613fd4565b61301a906040810190613ff4565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061353d92505050565b82828151811061306657613066613fbe565b6020026020010181905250808061307c90614050565b915050612f82565b50949350505050565b6041808202830160208101516040820151919092015160009260ff9190911691601b8314806130bf57508260ff16601c145b61310b5760405162461bcd60e51b815260206004820152601b60248201527f553a2062616420762076616c756520696e207369676e617475726500000000006044820152606401610581565b604080516000808252602082018084528a905260ff861692820192909252606081018490526080810183905260019060a0016020604051602081039080840390855afa15801561315f573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811661096a5760405162461bcd60e51b81526020600482015260176024820152760553a2065637265636f7665722072657475726e6564203604c1b6044820152606401610581565b6000816001600160a01b0316836001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613206573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061322a9190614119565b6001600160a01b0316149392505050565b6132458383613664565b604051636b8ab97d60e01b81526001600160a01b037f0000000000000000000000003712d49bed8335d3b90c34109a48d9cd5ee8daaf1690636b8ab97d90613291908690600401613f15565b600060405180830381600087803b1580156132ab57600080fd5b505af11580156132bf573d6000803e3d6000fd5b5050604051634ff4b8e160e11b81526001600160a01b037f0000000000000000000000003712d49bed8335d3b90c34109a48d9cd5ee8daaf169250639fe971c291506122969086908590600401613fa4565b6000602482101561335c5760405162461bcd60e51b815260206004820152601560248201527412d48e88125b9d985b1a590819185d1855985d5b1d605a1b6044820152606401610581565b6001600160a01b0384166133a65760405162461bcd60e51b815260206004820152601160248201527012d48e88125b9d985b1a59081d985d5b1d607a1b6044820152606401610581565b60006133b5836004818761431f565b8101906133c291906138de565b6001600160a01b03908116908616149150509392505050565b6001600160a01b03821660009081526020818152604080832084845260018082018452828520859055600282019093529083205460038201549192909190613423908261428e565b821461349c5760006003840161343a60018461428e565b8154811061344a5761344a613fbe565b600091825260208083209091015480835260028701909152604080832086905588835282209190915560038501805491925082918590811061348e5761348e613fbe565b600091825260209091200155505b826003018054806134af576134af614349565b600190038181906000526020600020016000905590556001935050505092915050565b6001600160a01b03821660009081526020819052604081205482116134f9575060006105c3565b608082901c61350a6127104361427b565b81111561351b5760009150506105c3565b50506001600160a01b0391909116600090815260208190526040902055600190565b60606000856001600160a01b03168585856040516024016135609392919061435f565b60408051601f198184030181529181526020820180516001600160e01b03166347b7819960e11b1790525161359591906142d6565b6000604051808303816000865af19150503d80600081146135d2576040519150601f19603f3d011682016040523d82523d6000602084013e6135d7565b606091505b50925090508080156135ea575060008251115b1561360a57818060200190518101906136039190614386565b9150613084565b81511561361b573d6000803e3d6000fd5b806130845760405162461bcd60e51b815260206004820152601960248201527810934e881d985d5b1d081a5b9d9bdad9481c995d995c9d1959603a1b6044820152606401610581565b61366e8282613786565b6040516313af403560e01b81526001600160a01b038316906313af40359061369a908490600401613f15565b600060405180830381600087803b1580156136b457600080fd5b505af11580156136c8573d6000803e3d6000fd5b505050506000306001600160a01b0316836040516024016136e99190613f15565b60408051601f198184030181529181526020820180516001600160e01b03166397e8f71760e01b1790525161371e91906142d6565b6000604051808303816000865af19150503d806000811461375b576040519150601f19603f3d011682016040523d82523d6000602084013e613760565b606091505b50509050806137815760405162461bcd60e51b8152600401610581906142e8565b505050565b60405162c7fe6f60e71b81526001600160a01b037f0000000000000000000000003712d49bed8335d3b90c34109a48d9cd5ee8daaf16906363ff3780906137d39085908590600401613fa4565b602060405180830381865afa1580156137f0573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061381491906140f7565b156138615760405162461bcd60e51b815260206004820181905260248201527f534d3a206e6577206f776e65722063616e6e6f7420626520677561726469616e6044820152606401610581565b5050565b50805460008255906000526020600020908101906138839190613886565b50565b5b8082111561389b5760008155600101613887565b5090565b6000602082840312156138b157600080fd5b81356001600160e01b03198116811461097057600080fd5b6001600160a01b038116811461388357600080fd5b6000602082840312156138f057600080fd5b8135610970816138c9565b60008060006040848603121561391057600080fd5b833561391b816138c9565b925060208401356001600160401b038082111561393757600080fd5b818601915086601f83011261394b57600080fd5b81358181111561395a57600080fd5b8760208260051b850101111561396f57600080fd5b6020830194508093505050509250925092565b60005b8381101561399d578181015183820152602001613985565b50506000910152565b600081518084526139be816020860160208601613982565b601f01601f19169290920160200192915050565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b82811015613a2757603f19888603018452613a158583516139a6565b945092850192908501906001016139f9565b5092979650505050505050565b60008060408385031215613a4757600080fd5b8235613a52816138c9565b946020939093013593505050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b0381118282101715613a9e57613a9e613a60565b604052919050565b60006001600160401b03821115613abf57613abf613a60565b50601f01601f191660200190565b600082601f830112613ade57600080fd5b8135613af1613aec82613aa6565b613a76565b818152846020838601011115613b0657600080fd5b816020850160208301376000918101602001919091529392505050565b60008060408385031215613b3657600080fd5b8235915060208301356001600160401b03811115613b5357600080fd5b613b5f85828601613acd565b9150509250929050565b60008060408385031215613b7c57600080fd5b8235613b87816138c9565b91506020830135613b97816138c9565b809150509250929050565b60008083601f840112613bb457600080fd5b5081356001600160401b03811115613bcb57600080fd5b602083019150836020828501011115613be357600080fd5b9250929050565b600080600060408486031215613bff57600080fd5b8335613c0a816138c9565b925060208401356001600160401b03811115613c2557600080fd5b613c3186828701613ba2565b9497909650939450505050565b634e487b7160e01b600052602160045260246000fd5b60058110613c7257634e487b7160e01b600052602160045260246000fd5b9052565b828152604081016109706020830184613c54565b60008060008060808587031215613ca057600080fd5b8435613cab816138c9565b93506020850135925060408501356001600160401b03811115613ccd57600080fd5b613cd987828801613acd565b949793965093946060013593505050565b60008060008060808587031215613d0057600080fd5b8435613d0b816138c9565b93506020850135925060408501356001600160401b03811115613d2d57600080fd5b613d3987828801613acd565b925050606085013560058110613d4e57600080fd5b939692955090935050565b600080600060608486031215613d6e57600080fd5b8335613d79816138c9565b92506020840135613d89816138c9565b91506040840135613d99816138c9565b809150509250925092565b60008060008060008060808789031215613dbd57600080fd5b8635613dc8816138c9565b955060208701356001600160401b0380821115613de457600080fd5b613df08a838b01613ba2565b9097509550604089013594506060890135915080821115613e1057600080fd5b50613e1d89828a01613ba2565b979a9699509497509295939492505050565b600080600060608486031215613e4457600080fd5b8335613e4f816138c9565b92506020840135613e5f816138c9565b915060408401356001600160401b03811115613e7a57600080fd5b613e8686828701613acd565b9150509250925092565b600080600080600060808688031215613ea857600080fd5b8535613eb3816138c9565b945060208601356001600160401b0380821115613ecf57600080fd5b613edb89838a01613ba2565b9096509450604088013593506060880135915080821115613efb57600080fd5b50613f0888828901613acd565b9150509295509295909350565b6001600160a01b0391909116815260200190565b60008060208385031215613f3c57600080fd5b82356001600160401b03811115613f5257600080fd5b613f5e85828601613ba2565b90969095509350505050565b602081016105c38284613c54565b602080825260129082015271424d3a206d757374206265206d6f64756c6560701b604082015260600190565b6001600160a01b0392831681529116602082015260400190565b634e487b7160e01b600052603260045260246000fd5b60008235605e19833603018112613fea57600080fd5b9190910192915050565b6000808335601e1984360301811261400b57600080fd5b8301803591506001600160401b0382111561402557600080fd5b602001915036819003821315613be357600080fd5b634e487b7160e01b600052601160045260246000fd5b6000600182016140625761406261403a565b5060010190565b604080825283519082018190526000906020906060840190828701845b828110156140ab5781516001600160a01b031684529284019290840190600101614086565b5050508381038285015284518082528583019183019060005b818110156140ea5783516001600160e01b031916835292840192918401916001016140c4565b5090979650505050505050565b60006020828403121561410957600080fd5b8151801515811461097057600080fd5b60006020828403121561412b57600080fd5b8151610970816138c9565b60208082526016908201527512d34e881b595d1a1bd9081b9bdd08185b1b1bddd95960521b604082015260600190565b60006020828403121561417857600080fd5b5051919050565b6001600160f81b0319888116825287166001820152606086901b6bffffffffffffffffffffffff191660028201526016810185905283516000906141ca816036850160208901613982565b909101603681019390935250605682015260760195945050505050565b8183823760009101908152919050565b60208082526018908201527712d48e88125b9d195c9b985b0818d85b1b0819985a5b195960421b604082015260600190565b60408152600061423c60408301856139a6565b90508260208301529392505050565b6020808252601690820152754b523a20496e76616c6964205369676e61747572657360501b604082015260600190565b808201808211156105c3576105c361403a565b818103818111156105c3576105c361403a565b6001600160a01b038416815282151560208201526060604082018190526000906142cd908301846139a6565b95945050505050565b60008251613fea818460208701613982565b6020808252601f908201527f534d3a2063616e63656c20616c6c206f7065726174696f6e206661696c656400604082015260600190565b6000808585111561432f57600080fd5b8386111561433c57600080fd5b5050820193919092039150565b634e487b7160e01b600052603160045260246000fd5b60018060a01b03841681528260208201526060604082015260006142cd60608301846139a6565b60006020828403121561439857600080fd5b81516001600160401b038111156143ae57600080fd5b8201601f810184136143bf57600080fd5b80516143cd613aec82613aa6565b8181528560208385010111156143e257600080fd5b6142cd82602083016020860161398256fea26469706673582212200b45be967ad1fe1cde69d34b9573a79a5b374c9e03b730b17f8d73d4fb90282664736f6c63430008110033

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

0000000000000000000000003712d49bed8335d3b90c34109a48d9cd5ee8daaf00000000000000000000000083c2defd5bb812b5b15f28f2b9534a3c70481bc10000000000000000000000007bf09a75da7e88977150f452135ead9c90729cbd

-----Decoded View---------------
Arg [0] : _storageAddr (address): 0x3712d49BED8335D3b90c34109A48d9cD5ee8Daaf
Arg [1] : _kresusRegistry (address): 0x83c2DEFd5bb812b5B15F28f2b9534A3C70481bC1
Arg [2] : _kresusGuardian (address): 0x7Bf09A75DA7e88977150f452135Ead9c90729cbd

-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 0000000000000000000000003712d49bed8335d3b90c34109a48d9cd5ee8daaf
Arg [1] : 00000000000000000000000083c2defd5bb812b5b15f28f2b9534a3c70481bc1
Arg [2] : 0000000000000000000000007bf09a75da7e88977150f452135ead9c90729cbd


Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

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

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ 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.