ETH Price: $2,387.10 (-0.67%)

Contract

0x0fA1C8e15C077521ecC31D84a6Dfd2b5e86F3a36
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Execute195179022024-03-26 10:04:35163 days ago1711447475IN
0x0fA1C8e1...5e86F3a36
0 ETH0.0014035823.72765827
Execute194965672024-03-23 10:00:11166 days ago1711188011IN
0x0fA1C8e1...5e86F3a36
0 ETH0.0010315216.9751526
Execute194965522024-03-23 9:57:11166 days ago1711187831IN
0x0fA1C8e1...5e86F3a36
0 ETH0.0011275916.64497554
Execute194823252024-03-21 10:03:59168 days ago1711015439IN
0x0fA1C8e1...5e86F3a36
0 ETH0.003303326.83236046
Execute194686392024-03-19 11:57:11170 days ago1710849431IN
0x0fA1C8e1...5e86F3a36
0 ETH0.0027978447.29763428
Execute194681582024-03-19 10:20:11170 days ago1710843611IN
0x0fA1C8e1...5e86F3a36
0 ETH0.0041463270.09373167
Execute194680842024-03-19 10:05:11170 days ago1710842711IN
0x0fA1C8e1...5e86F3a36
0 ETH0.0048221778.3354108
Execute194610912024-03-18 10:29:11171 days ago1710757751IN
0x0fA1C8e1...5e86F3a36
0 ETH0.0013680522.04876909
Execute194610622024-03-18 10:23:23171 days ago1710757403IN
0x0fA1C8e1...5e86F3a36
0 ETH0.0030902324.92824784
Execute194609422024-03-18 9:59:11171 days ago1710755951IN
0x0fA1C8e1...5e86F3a36
0 ETH0.0031948825.36448635
Execute194609272024-03-18 9:56:11171 days ago1710755771IN
0x0fA1C8e1...5e86F3a36
0 ETH0.0033515527.21784376
Execute194603592024-03-18 8:00:47171 days ago1710748847IN
0x0fA1C8e1...5e86F3a36
0 ETH0.0019490322.28464098
Execute194603492024-03-18 7:58:47171 days ago1710748727IN
0x0fA1C8e1...5e86F3a36
0 ETH0.0019627419.1433585
Execute194483402024-03-16 15:27:35172 days ago1710602855IN
0x0fA1C8e1...5e86F3a36
0 ETH0.0021479935.34801982
Execute194482152024-03-16 15:02:11172 days ago1710601331IN
0x0fA1C8e1...5e86F3a36
0 ETH0.0024051435.5033742
Execute194433752024-03-15 22:40:11173 days ago1710542411IN
0x0fA1C8e1...5e86F3a36
0 ETH0.0016657128.15895569
Execute194433752024-03-15 22:40:11173 days ago1710542411IN
0x0fA1C8e1...5e86F3a36
0 ETH0.0019529928.15895569
Execute194430212024-03-15 21:28:11173 days ago1710538091IN
0x0fA1C8e1...5e86F3a36
0 ETH0.0021160334.82207819
Execute194419902024-03-15 18:00:11173 days ago1710525611IN
0x0fA1C8e1...5e86F3a36
0 ETH0.0021466836.2897478
Execute194419832024-03-15 17:58:35173 days ago1710525515IN
0x0fA1C8e1...5e86F3a36
0 ETH0.0024439734.92187439
Execute194419312024-03-15 17:48:11173 days ago1710524891IN
0x0fA1C8e1...5e86F3a36
0 ETH0.0019796233.46562619
Execute194401802024-03-15 11:54:35174 days ago1710503675IN
0x0fA1C8e1...5e86F3a36
0 ETH0.0039020738.42435777
Execute194401512024-03-15 11:48:47174 days ago1710503327IN
0x0fA1C8e1...5e86F3a36
0 ETH0.0050783835.54625918
Execute194398072024-03-15 10:39:47174 days ago1710499187IN
0x0fA1C8e1...5e86F3a36
0 ETH0.0019906732.75919471
Execute194396872024-03-15 10:15:23174 days ago1710497723IN
0x0fA1C8e1...5e86F3a36
0 ETH0.0020606534.62231184
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 which consists of:
 * - Kresus Relayer
 * - Security Manager
 * - Transaction Manager
 * Consists of fundamental functionalities:
 * - Get required signatures.
 * - Validate signatures.
 * - Adding and authorizing new modules.
 */
contract KresusModule is BaseModule, KresusRelayer, SecurityManager, TransactionManager {

    // address of kresus guardian responsible for enable/disable, lock/unlock vault and executeBequeathal.
    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");
    }

    /**
     * @notice Function to get the signature requirement to cancel operations of a vault.
     * Operations which are queued can be cancelled by using the requirement provided by this 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 new module. New modules which are registered can be authorized for each {ProxyVault}.
     * @param _module The module address which has to be registered.
     * @param _name The name of the module.
     */
    function registerModule(address _module, string calldata _name) external;

    /**
     * @notice Deregisters a module.
     * @param _module The module address.
     */
    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 of the module.
     */
    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, else false.
     */
    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, else false.
     */
    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";

/**
 * @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
    }

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

    // The guardians storage
    IStorage internal immutable _storage;

    // Kresus 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");
        _;
    }

    /**
     * @notice 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 kresus 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, else false.
     */
    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.
     * @return True if `_addr` is the owner of `_vault`, else false.
     */
    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.
     * @return _isSupported True if `_methodId` is supported, else false.
     */
    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");

        if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {
            revert("U: Invalid s value");
        }

        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 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"
            );
            if(relayer[_vault].queue.length > 0) {
                removeQueue(_vault, stack.signHash);
            }
            (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;
        }
        
        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 time delay and the valid signature requirement that must be provided to execute a
     * specific relayed transaction.
     * @param _vault The target vault.
     * @param _data The data of the relayed transaction.
     * @return Time delay to execute the transaction and its 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, else false.
     */
    function validateSignatures(
        address _vault,
        bytes32 _actionHash,
        bytes memory _data,
        Signature _option
    ) public view virtual returns(bool);

    /**
     * @notice Gets the required signature requirement to cancel the request which is queued.
     * @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 ERC1077.
     * (see https://eips.ethereum.org/EIPS/eip-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 `_nonce` is updated for `_vault`.
     * @param _vault The target vault.
     * @param _nonce The nonce.
     * @return True if the transaction is unique else false.
     */
    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, else true.
     */
    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 True if the underlying action of `_actionHash` is queued, else false.
     */
    function isActionQueued(
        address _vault,
        bytes32 _actionHash
    )
        public
        view
        returns (bool)
    {
        return (relayer[_vault].queuedTransactions[_actionHash] > 0);
    }

    /**
     * @notice Returns execution time for a given queued action.
     * @param _vault The target vault.
     * @param _actionHash Hash of the action to be checked.
     * @return Execution time for a given queued action, returns zero if `_actionHash` is not queued.
     */
    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 which involves:
 * - Managing guardians, trustee and ownership.
 * - Managing time delay.
 * - Managing status of a vault (lock/unlock, enable/disable).
 */
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);
    event Disabled(address indexed vault);

    /**
     * @notice Function to lock `_vault`. Cancels all the queued operations.
     * @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 Function to update the time delay for `_vault`
     * @param _vault The target vault.
     * @param _newTimeDelay The new time delay to update in seconds.
     */
    function setTimeDelay(
        address _vault,
        uint256 _newTimeDelay
    )
        external
        onlySelf()
    {
        _storage.setTimeDelay(_vault, _newTimeDelay);
        emit TimeDelayChanged(_vault, _newTimeDelay);
    }

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


    /**
     * @notice Function to changes the human group public address for `_vault`.
     * Replaces the human group address with `_guardian`.
     * @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 remove human guardians for `_vault`.
     * @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 for `_vault`.
     * Replaces the human group address with `_guardian`.
     * @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 Function to add trustee for `_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 Function to remove trustee for `_vault`.
     * @param _vault The target vault.
     */
    function removeTrustee(
        address _vault
    )
        external
        onlySelf()
    {
        _storage.setTrustee(_vault, ZERO_ADDRESS);
        emit TrusteeChanged(_vault, ZERO_ADDRESS);
    }

    /**
     * @notice Function to set the current trustee address as the new owner for `_vault`. 
     * After change in owner sets the current trustee address to zero address.
     * @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 Function to enable `_vault`.
     * @param _vault The target vault.
     */
    function enable(
        address _vault
    )
        external
        onlySelf()
    {
        _storage.enable(_vault);
        emit Enabled(_vault);
    }

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

    /**
     * @notice Function to transfer ownership to `_newOwner` and changes the kbg address to `_newKbg` for `_vault`.
     * @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 `_newOwner` is valid to be the new owner for `_vault`.
     * @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. Manages static calls made to a vault.
 */
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 `_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 `_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).
     * @param _interfaceID Bytes4 interface id of an interface.
     * @return True if this contract implements the interface, else false.
     */
    function supportsInterface(
        bytes4 _interfaceID
    )
        external
        pure
        returns (bool)
    {
        return  _interfaceID == ERC165_INTERFACE ||
                _interfaceID == (ERC1155_RECEIVED ^ ERC1155_BATCH_RECEIVED) ||
                _interfaceID == ERC721_RECEIVED;
    }

    /**
     * @notice Implementation of EIP 1271.
     * Should return whether the `_signature` provided is valid for `_msgHash`.
     * @param _msgHash Hash of a message signed on the behalf of `address(this)`.
     * @param _signature Signature byte array associated with `_msgHash`.
     * @return If signature is valid returns magic value {ERC1271_IS_VALID_SIGNATURE}.
     */
    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) 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 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.
     * @return The trustee address for a 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`, else false.
     */
    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`, else false.
     */
    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`, else false.
     */
    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 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

[{"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"}],"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":"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"}],"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"}]

60e06040523480156200001157600080fd5b5060405162004637380380620046378339810160408190526200003491620000c9565b6001600160a01b0380841660805280831660a05281166200009b5760405162461bcd60e51b815260206004820152601360248201527f4b4d3a20496e76616c6964206164647265737300000000000000000000000000604482015260640160405180910390fd5b6001600160a01b031660c052506200011d9050565b6001600160a01b0381168114620000c657600080fd5b50565b600080600060608486031215620000df57600080fd5b8351620000ec81620000b0565b6020850151909350620000ff81620000b0565b60408501519092506200011281620000b0565b809150509250925092565b60805160a05160c05161441162000226600039600081816104c001528181611b8e0152611c1b0152600081816108aa01528181610f23015281816114b2015261216201526000818161062001528181610ab401528181610c1a01528181610cf701528181610e2801528181610fc6015281816110f4015281816111880152818161121c015281816112d2015281816113fa015281816116d70152818161189601528181611a2501528181611b0d01528181611be2015281816122c8015281816123a201528181612601015281816126f90152818161293b015281816129ae01528181612cb001528181612d8a01528181613276015281816132f201526137b601526144116000f3fe608060405234801561001057600080fd5b506004361061019a5760003560e01c8063694c596b116100e4578063a5efb23511610092578063a5efb2351461046f578063ac419cfc14610482578063c0d91eaf14610495578063c10cab45146104a8578063cbb98bee146104bb578063ce1d3e2f146104ef578063e6c09edf1461050f578063f435f5a7146105225761019a565b8063694c596b146103ea5780636b760a94146103fd5780636c459a281461041057806371bf3af11461042357806375033f4b146104365780638a85073b1461044957806397e8f7171461045c5761019a565b80632d0335ab1161014c5780632d0335ab1461032e5780632f6c493c14610357578063304e0bb01461036a5780633b73d67f1461037d5780635ad5f3e41461039e5780635bfa1b68146103b15780635d80f160146103c457806368769fd8146103d75761019a565b806301ffc9a71461023b5780630312050614610263578063075a6444146102765780630a6dd219146102965780631626ba7e146102dc57806319a145c71461030857806325b509341461031b575b60006101dc6000368080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061053592505050565b90506001600160e01b03198116630a85bd0160e11b148061020d57506001600160e01b0319811663f23a6e6160e01b145b8061022857506001600160e01b0319811663bc197c8160e01b145b156102395760046000803760206000f35b005b61024e6102493660046138b9565b610592565b60405190151581526020015b60405180910390f35b6102396102713660046138f8565b6105e4565b610289610284366004613915565b6106c3565b60405161025a91906139ec565b6102ce6102a4366004613a4e565b6001600160a01b039190911660009081526020818152604080832093835260019093019052205490565b60405190815260200161025a565b6102ef6102ea366004613b3d565b610992565b6040516001600160e01b0319909116815260200161025a565b610239610316366004613a4e565b610a69565b61024e6103293660046138b9565b610b57565b6102ce61033c3660046138f8565b6001600160a01b031660009081526020819052604090205490565b6102396103653660046138f8565b610bde565b610239610378366004613b83565b610cb8565b61039061038b366004613c04565b610dca565b60405161025a929190613c90565b6102ce6103ac366004613ca4565b61160d565b6102396103bf3660046138f8565b61169b565b61024e6103d2366004613a4e565b611775565b6102396103e5366004613b83565b6117a1565b61024e6103f8366004613d04565b61193b565b61023961040b366004613d73565b611c59565b61024e61041e366004613dbe565b611cd1565b610239610431366004613e49565b612126565b6102396104443660046138f8565b61228c565b610239610457366004613b83565b61236b565b61023961046a3660046138f8565b612470565b61028961047d366004613915565b612598565b610239610490366004613b83565b6125ca565b6102396104a3366004613c04565b61279e565b6102396104b6366004613eaa565b612a21565b6104e27f000000000000000000000000000000000000000000000000000000000000000081565b60405161025a9190613f2f565b6105026104fd366004613f43565b612b6b565b60405161025a9190613f84565b61023961051d3660046138f8565b612c74565b6102396105303660046138f8565b612d4e565b600060048251101561058a5760405162461bcd60e51b81526020600482015260196024820152780aa744092dcecc2d8d2c840cceadcc6e8d2dedca0e4caccd2f603b1b60448201526064015b60405180910390fd5b506020015190565b60006001600160e01b031982166301ffc9a760e01b14806105c357506001600160e01b03198216630271189760e51b145b806105de57506001600160e01b03198216630a85bd0160e11b145b92915050565b6105ed33612ede565b6106095760405162461bcd60e51b815260040161058190613f92565b60405163da209d5160e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063da209d5190610658908490600090600401613fbe565b600060405180830381600087803b15801561067257600080fd5b505af1158015610686573d6000803e3d6000fd5b5050604051600092506001600160a01b03841691507f313fbef49831f81de756df207bd6dd33dc4f5757ebd556a3375e05c1050c3aa4908390a350565b60606106ce33612ede565b6106ea5760405162461bcd60e51b815260040161058190613f92565b816000816001600160401b0381111561070557610705613a7a565b60405190808252806020026020018201604052801561072e578160200160208202803683370190505b5090506000826001600160401b0381111561074b5761074b613a7a565b604051908082528060200260200182016040528015610774578160200160208202803683370190505b50905060005b838110156108925786868281811061079457610794613fd8565b90506020028101906107a69190613fee565b6107b49060208101906138f8565b8382815181106107c6576107c6613fd8565b60200260200101906001600160a01b031690816001600160a01b0316815250506108558787838181106107fb576107fb613fd8565b905060200281019061080d9190613fee565b61081b90604081019061400e565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061053592505050565b82828151811061086757610867613fd8565b6001600160e01b0319909216602092830291909101909101528061088a8161406a565b91505061077a565b50604051634ab00efb60e01b81526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690634ab00efb906108e19085908590600401614083565b602060405180830381865afa1580156108fe573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109229190614111565b61097a5760405162461bcd60e51b8152602060048201526024808201527f544d3a20416464726573736573206f722053696773206e6f7420726567697374604482015263195c995960e21b6064820152608401610581565b610985878787612eec565b93505050505b9392505050565b600081516041146109e55760405162461bcd60e51b815260206004820152601c60248201527f544d3a20696e76616c6964207369676e6174757265206c656e677468000000006044820152606401610581565b60006109f38484600061304c565b90506109ff33826131d6565b610a405760405162461bcd60e51b81526020600482015260126024820152712a269d1024b73b30b634b21039b4b3b732b960711b6044820152606401610581565b507f1626ba7e356f5979dd355a3d2bfb43e80420a480c3b854edce286a82d74968699392505050565b610a7233612ede565b610a8e5760405162461bcd60e51b815260040161058190613f92565b6040516319a145c760e01b81526001600160a01b038381166004830152602482018390527f000000000000000000000000000000000000000000000000000000000000000016906319a145c790604401600060405180830381600087803b158015610af857600080fd5b505af1158015610b0c573d6000803e3d6000fd5b50505050816001600160a01b03167fcbe22d4428901024069c2997f8626afe4fe1a1e280a8de9618d51351b9b265b782604051610b4b91815260200190565b60405180910390a25050565b60006001600160e01b03198216630b135d3f60e11b1480610b8857506001600160e01b03198216630a85bd0160e11b145b80610ba357506001600160e01b031982166301ffc9a760e01b145b80610bbe57506001600160e01b0319821663f23a6e6160e01b145b806105de57506001600160e01b0319821663bc197c8160e01b1492915050565b610be733612ede565b610c035760405162461bcd60e51b815260040161058190613f92565b604051630bdb124f60e21b81526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690632f6c493c90610c4f908490600401613f2f565b600060405180830381600087803b158015610c6957600080fd5b505af1158015610c7d573d6000803e3d6000fd5b50506040516001600160a01b03841692507f7e6adfec7e3f286831a0200a754127c171a2da564078722cb97704741bbdb0ea9150600090a250565b610cc133612ede565b610cdd5760405162461bcd60e51b815260040161058190613f92565b604051630435586b60e11b81526000906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063086ab0d690610d2c908690600401613f2f565b602060405180830381865afa158015610d49573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d6d9190614133565b9050610d7a838284613255565b806001600160a01b0316836001600160a01b03167f02508c98f5b30f12e216477136240f270c87a5992a7c6d5e0b8960a9f6f6af8984604051610dbd9190613f2f565b60405180910390a3505050565b6000806000610e0e85858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061053592505050565b604051631293efbb60e21b81529091506001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690634a4fbeec90610e5d908990600401613f2f565b602060405180830381865afa158015610e7a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e9e9190614111565b15610faf576001600160e01b03198116630bdb124f60e21b1480610ed257506001600160e01b03198116630304e0bb60e41b145b80610eed57506001600160e01b0319811663e6c09edf60e01b145b610f095760405162461bcd60e51b815260040161058190614150565b633424edb160e21b6001600160e01b0319821601610faf577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663e06902ea6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610f7f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fa39190614180565b60039250925050611605565b604051634f6c171d60e01b81526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690634f6c171d90610ffb908990600401613f2f565b602060405180830381865afa158015611018573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061103c9190614111565b156110c2576001600160e01b03198116630304e0bb60e41b148061107057506001600160e01b0319811663a5efb23560e01b145b8061108b57506001600160e01b031981166301d6991160e21b145b806110a657506001600160e01b03198116630b7f436d60e31b145b6110c25760405162461bcd60e51b815260040161058190614150565b635a104dcb60e01b6001600160e01b03198216016112a057604051633b325d3760e01b81526000906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690633b325d3790611129908a90600401613f2f565b602060405180830381865afa158015611146573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061116a9190614111565b90508061120557604051634a81d26d60e11b81526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690639503a4da906111bd908a90600401613f2f565b602060405180830381865afa1580156111da573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111fe9190614180565b6001611295565b604051634a81d26d60e11b81526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690639503a4da90611251908a90600401613f2f565b602060405180830381865afa15801561126e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112929190614180565b60025b935093505050611605565b633e2966ef60e21b6001600160e01b031982160161136e57604051633b325d3760e01b81526000906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690633b325d3790611307908a90600401613f2f565b602060405180830381865afa158015611324573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113489190614111565b905080611358576000600161135d565b600060025b8160ff169150935093505050611605565b630bca0a5960e01b6001600160e01b031982160161139457600060049250925050611605565b6001600160e01b03198116630d0ed3fb60e31b14806113c357506001600160e01b03198116631add82a560e21b145b806113de57506001600160e01b031981166319a145c760e01b145b1561147c57604051634a81d26d60e11b81526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690639503a4da9061142f908990600401613f2f565b602060405180830381865afa15801561144c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114709190614180565b60019250925050611605565b6001600160e01b031981166375033f4b60e01b14806114ab57506001600160e01b03198116630189028360e11b145b1561150e577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663c15d8b966040518163ffffffff1660e01b8152600401602060405180830381865afa15801561144c573d6000803e3d6000fd5b6001600160e01b03198116638a85073b60e01b148061153d57506001600160e01b03198116632b10673f60e21b145b8061155857506001600160e01b031981166371bf3af160e01b145b1561156b57600060019250925050611605565b6001600160e01b03198116630b7f436d60e31b148061159a57506001600160e01b0319811663e6c09edf60e01b145b806115b557506001600160e01b03198116630304e0bb60e41b145b156115c857600060049250925050611605565b60405162461bcd60e51b815260206004820152601260248201527112d34e881d5b9adb9bdddb881b595d1a1bd960721b6044820152606401610581565b935093915050565b60405160009061163190601960f81b90839088908890889046908990602001614199565b60408051601f198184030181529082905280516020918201207f19457468657265756d205369676e6564204d6573736167653a0a33320000000091830191909152603c820152605c016040516020818303038152906040528051906020012090505b949350505050565b6116a433612ede565b6116c05760405162461bcd60e51b815260040161058190613f92565b604051630b7f436d60e31b81526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690635bfa1b689061170c908490600401613f2f565b600060405180830381600087803b15801561172657600080fd5b505af115801561173a573d6000803e3d6000fd5b50506040516001600160a01b03841692507f44bcce471802f9158ee4390426e4a931d186757cc50d302f6747504c17516d129150600090a250565b6001600160a01b0391909116600090815260208181526040808320938352600190930190522054151590565b6117aa33612ede565b6117c65760405162461bcd60e51b815260040161058190613f92565b816001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611804573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118289190614133565b6001600160a01b0316816001600160a01b03160361187f5760405162461bcd60e51b815260206004820152601460248201527329a69d1024b73b30b634b21033bab0b93234b0b760611b6044820152606401610581565b604051630d0ed3fb60e31b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906368769fd8906118cd9085908590600401613fbe565b600060405180830381600087803b1580156118e757600080fd5b505af11580156118fb573d6000803e3d6000fd5b50506040516001600160a01b038085169350851691507f6e60a4dea8b0048bb934b375dde93967bc9163c35c0b9d5cfe0dc1f04e5e2d9e90600090a35050565b600060418351101561194f57506000611693565b600061195d8585600061304c565b9050600083600481111561197357611973613c58565b036119f657856001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156119b6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119da9190614133565b6001600160a01b0316816001600160a01b031614915050611693565b6002836004811115611a0a57611a0a613c58565b03611aa55760405162c7fe6f60e71b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906363ff378090611a5c9089908590600401613fbe565b602060405180830381865afa158015611a79573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a9d9190614111565b915050611693565b6001836004811115611ab957611ab9613c58565b1480611ad657506003836004811115611ad457611ad4613c58565b145b15611c1957604184511115611bcb576000611af38686600161304c565b60405163be546e0d60e01b81529091506001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063be546e0d90611b44908a908690600401613fbe565b602060405180830381865afa158015611b61573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b859190614111565b8015611bc257507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316816001600160a01b0316145b92505050611693565b60405163be546e0d60e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063be546e0d90611a5c9089908590600401613fbe565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316816001600160a01b031614915050949350505050565b611c6233612ede565b611c7e5760405162461bcd60e51b815260040161058190613f92565b611c89838383613255565b826001600160a01b03167fab0ca8c1a4d3a9baa49449ec32c98bdc60c6e9ecec571ed15582b90dca7d9e298383604051611cc4929190613fbe565b60405180910390a2505050565b6000611cde87878761332b565b611d2a5760405162461bcd60e51b815260206004820152601d60248201527f4b523a20546172676574206f66205f6461746120213d205f7661756c740000006044820152606401610581565b611d5460408051608081019091528060008152600060208201819052604082015260609081015290565b6000611d61898989610dca565b83816004811115611d7457611d74613c58565b6004811115611d8557611d85613c58565b8152508192505050611dd18960008a8a8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508c925061160d915050565b60208301819052611de3908a90611775565b15611f8e576001600160a01b0389166000908152602081815260408083208583015184526001019091529020544211611e555760405162461bcd60e51b815260206004820152601460248201527312d48e88151a5b59481b9bdd08195e1c1a5c995960621b6044820152606401610581565b6001600160a01b03891660009081526020819052604090206003015415611e8657611e848983602001516133f5565b505b6040513090611e98908a908a90614201565b6000604051808303816000865af19150503d8060008114611ed5576040519150601f19603f3d011682016040523d82523d6000602084013e611eda565b606091505b506060840152151560408301819052611f305760405162461bcd60e51b815260206004820152601860248201527712d48e88125b9d195c9b985b0818d85b1b0819985a5b195960421b6044820152606401610581565b81604001511515896001600160a01b03167f7da4525a280527268ba2e963ee6c1b18f43c9507bcb1d2560f652ab17c76e90a84606001518560200151604051611f7a929190614211565b60405180910390a35060400151905061211c565b611fd689836020015187878080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250508751915061193b9050565b611ff25760405162461bcd60e51b815260040161058190614233565b611ffc89876134ec565b6120405760405162461bcd60e51b815260206004820152601560248201527412d48e88111d5c1b1a58d85d19481c995c5d595cdd605a1b6044820152606401610581565b8015611e865760006120528242614263565b6001600160a01b038b166000818152602081815260408083208883018051855260018083018552928520879055858552848452516003909101805480840182558186529385209093015592909152549192506120ad91614276565b6001600160a01b038b1660008181526020818152604080832088830180518552600290910183529281902094909455905183518581529182015290917fa738aec4c92150604d027c7e038eb5f4889db730c1b895700442dad4b90ba665910160405180910390a2600193505050505b9695505050505050565b61212f33612ede565b61214b5760405162461bcd60e51b815260040161058190613f92565b604051630bcd4ebb60e01b81526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690630bcd4ebb90612197908590600401613f2f565b602060405180830381865afa1580156121b4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121d89190614111565b6122245760405162461bcd60e51b815260206004820152601c60248201527f4b4d3a206d6f64756c65206973206e6f742072656769737465726564000000006044820152606401610581565b604051632411c8f960e21b81526001600160a01b0384169063904723e4906122559085906001908690600401614289565b600060405180830381600087803b15801561226f57600080fd5b505af1158015612283573d6000803e3d6000fd5b50505050505050565b61229533612ede565b6122b15760405162461bcd60e51b815260040161058190613f92565b604051630d0ed3fb60e31b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906368769fd890612300908490600090600401613fbe565b600060405180830381600087803b15801561231a57600080fd5b505af115801561232e573d6000803e3d6000fd5b5050604051600092506001600160a01b03841691507f6e60a4dea8b0048bb934b375dde93967bc9163c35c0b9d5cfe0dc1f04e5e2d9e908390a350565b61237433612ede565b6123905760405162461bcd60e51b815260040161058190613f92565b604051632ad7108960e21b81526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063ab5c4224906123df908690600401613f2f565b602060405180830381865afa1580156123fc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124209190614133565b6001600160a01b03161461187f5760405162461bcd60e51b815260206004820152601760248201527629a69d1021b0b73737ba1030b2321033bab0b93234b0b760491b6044820152606401610581565b61247933612ede565b6124955760405162461bcd60e51b815260040161058190613f92565b6001600160a01b038116600090815260208190526040812060030154905b81811015612538576001600160a01b03831660009081526020819052604081206003018054839081106124e8576124e8613fd8565b6000918252602080832091909101546001600160a01b03871683528282526040808420918452600182018352808420849055600290910190915281205550806125308161406a565b9150506124b3565b506001600160a01b03821660009081526020819052604081206125609160039091019061387f565b6040516001600160a01b038316907fcb3a402591669c34ab2f5a32672eb79a626343ceea975d0b1be66ce67298e76f90600090a25050565b60606125a333612ede565b6125bf5760405162461bcd60e51b815260040161058190613f92565b611693848484612eec565b6125d333612ede565b6125ef5760405162461bcd60e51b815260040161058190613f92565b604051630435586b60e11b81526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063086ab0d69061263e908690600401613f2f565b602060405180830381865afa15801561265b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061267f9190614133565b6001600160a01b031614801561269d57506001600160a01b03811615155b6126e25760405162461bcd60e51b8152602060048201526016602482015275534d3a2043616e6e6f7420616464207472757374656560501b6044820152606401610581565b60405163da209d5160e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063da209d51906127309085908590600401613fbe565b600060405180830381600087803b15801561274a57600080fd5b505af115801561275e573d6000803e3d6000fd5b50506040516001600160a01b038085169350851691507f313fbef49831f81de756df207bd6dd33dc4f5757ebd556a3375e05c1050c3aa490600090a35050565b82336001600160a01b038216146127f25760405162461bcd60e51b815260206004820152601860248201527710934e8818d85b1b195c881b5d5cdd081899481d985d5b1d60421b6044820152606401610581565b60008061280184860186613a4e565b91509150816001600160a01b0316866001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561284d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128719190614133565b6001600160a01b0316036128b95760405162461bcd60e51b815260206004820152600f60248201526e4b4d3a20496e76616c6964204b424760881b6044820152606401610581565b604051634a933b1f60e01b81526001600160a01b03871690634a933b1f906128e5903090600401613f2f565b600060405180830381600087803b1580156128ff57600080fd5b505af1158015612913573d6000803e3d6000fd5b50506040516319a145c760e01b81526001600160a01b038981166004830152602482018590527f00000000000000000000000000000000000000000000000000000000000000001692506319a145c79150604401600060405180830381600087803b15801561298157600080fd5b505af1158015612995573d6000803e3d6000fd5b5050604051634ff4b8e160e11b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169250639fe971c291506129e79089908690600401613fbe565b600060405180830381600087803b158015612a0157600080fd5b505af1158015612a15573d6000803e3d6000fd5b50505050505050505050565b6000612a6786600087878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525089925061160d915050565b90506000612a9287600060405180604001604052806002815260200161060f60f31b8152508761160d565b9050612a9e8783611775565b612add5760405162461bcd60e51b815260206004820152601060248201526f096a4744092dcecc2d8d2c840d0c2e6d60831b6044820152606401610581565b6000612ae98787612b6b565b9050612af78883868461193b565b612b135760405162461bcd60e51b815260040161058190614233565b612b1d88846133f5565b50876001600160a01b03167ff9303c741b41fde5495cd4aa8eb1ff8c2912281060edd43056567cce727d627784604051612b5991815260200190565b60405180910390a25050505050505050565b600080612bad84848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061053592505050565b90506001600160e01b03198116630d0ed3fb60e31b1480612bde57506001600160e01b031981166375033f4b60e01b145b80612bf957506001600160e01b031981166319a145c760e01b145b80612c1457506001600160e01b03198116631add82a560e21b145b80612c2f57506001600160e01b03198116630189028360e11b145b80612c4a57506001600160e01b0319811663a5efb23560e01b145b80612c6557506001600160e01b03198116630bdb124f60e21b145b156115c85760009150506105de565b612c7d33612ede565b612c995760405162461bcd60e51b815260040161058190613f92565b60405163e6c09edf60e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063e6c09edf90612ce5908490600401613f2f565b600060405180830381600087803b158015612cff57600080fd5b505af1158015612d13573d6000803e3d6000fd5b50506040516001600160a01b03841692507ff54453d15e2e6aee566733e6da03165ea58500408e802e05aa4e75f2408f59fe9150600090a250565b612d5733612ede565b612d735760405162461bcd60e51b815260040161058190613f92565b60405163f435f5a760e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063f435f5a790612dbf908490600401613f2f565b600060405180830381600087803b158015612dd957600080fd5b505af1158015612ded573d6000803e3d6000fd5b505050506000306001600160a01b031682604051602401612e0e9190613f2f565b60408051601f198184030181529181526020820180516001600160e01b03166397e8f71760e01b17905251612e4391906142be565b6000604051808303816000865af19150503d8060008114612e80576040519150601f19603f3d011682016040523d82523d6000602084013e612e85565b606091505b5050905080612ea65760405162461bcd60e51b8152600401610581906142d0565b6040516001600160a01b038316907f44427e3003a08f22cf803894075ac0297524e09e521fc1c15bc91741ce3dc15990600090a25050565b6001600160a01b0316301490565b60606000826001600160401b03811115612f0857612f08613a7a565b604051908082528060200260200182016040528015612f3b57816020015b6060815260200190600190039081612f265790505b50905060005b838110156130435761301386868684818110612f5f57612f5f613fd8565b9050602002810190612f719190613fee565b612f7f9060208101906138f8565b878785818110612f9157612f91613fd8565b9050602002810190612fa39190613fee565b60200135888886818110612fb957612fb9613fd8565b9050602002810190612fcb9190613fee565b612fd990604081019061400e565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061355792505050565b82828151811061302557613025613fd8565b6020026020010181905250808061303b9061406a565b915050612f41565b50949350505050565b6041808202830160208101516040820151919092015160009260ff9190911691601b83148061307e57508260ff16601c145b6130ca5760405162461bcd60e51b815260206004820152601b60248201527f553a2062616420762076616c756520696e207369676e617475726500000000006044820152606401610581565b6fa2a8918ca85bafe22016d0b997e4df60600160ff1b038111156131255760405162461bcd60e51b8152602060048201526012602482015271553a20496e76616c696420732076616c756560701b6044820152606401610581565b604080516000808252602082018084528a905260ff861692820192909252606081018490526080810183905260019060a0016020604051602081039080840390855afa158015613179573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166109855760405162461bcd60e51b81526020600482015260176024820152760553a2065637265636f7665722072657475726e6564203604c1b6044820152606401610581565b6000816001600160a01b0316836001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613220573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132449190614133565b6001600160a01b0316149392505050565b61325f838361367e565b604051636b8ab97d60e01b81526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690636b8ab97d906132ab908690600401613f2f565b600060405180830381600087803b1580156132c557600080fd5b505af11580156132d9573d6000803e3d6000fd5b5050604051634ff4b8e160e11b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169250639fe971c291506122559086908590600401613fbe565b600060248210156133765760405162461bcd60e51b815260206004820152601560248201527412d48e88125b9d985b1a590819185d1855985d5b1d605a1b6044820152606401610581565b6001600160a01b0384166133c05760405162461bcd60e51b815260206004820152601160248201527012d48e88125b9d985b1a59081d985d5b1d607a1b6044820152606401610581565b60006133cf8360048187614307565b8101906133dc91906138f8565b6001600160a01b03908116908616149150509392505050565b6001600160a01b0382166000908152602081815260408083208484526001808201845282852085905560028201909352908320546003820154919290919061343d9082614276565b82146134b657600060038401613454600184614276565b8154811061346457613464613fd8565b60009182526020808320909101548083526002870190915260408083208690558883528220919091556003850180549192508291859081106134a8576134a8613fd8565b600091825260209091200155505b826003018054806134c9576134c9614331565b600190038181906000526020600020016000905590556001935050505092915050565b6001600160a01b0382166000908152602081905260408120548211613513575060006105de565b608082901c61352461271043614263565b8111156135355760009150506105de565b50506001600160a01b0391909116600090815260208190526040902055600190565b60606000856001600160a01b031685858560405160240161357a93929190614347565b60408051601f198184030181529181526020820180516001600160e01b03166347b7819960e11b179052516135af91906142be565b6000604051808303816000865af19150503d80600081146135ec576040519150601f19603f3d011682016040523d82523d6000602084013e6135f1565b606091505b5092509050808015613604575060008251115b15613624578180602001905181019061361d919061436e565b9150613043565b815115613635573d6000803e3d6000fd5b806130435760405162461bcd60e51b815260206004820152601960248201527810934e881d985d5b1d081a5b9d9bdad9481c995d995c9d1959603a1b6044820152606401610581565b61368882826137a0565b6040516313af403560e01b81526001600160a01b038316906313af4035906136b4908490600401613f2f565b600060405180830381600087803b1580156136ce57600080fd5b505af11580156136e2573d6000803e3d6000fd5b505050506000306001600160a01b0316836040516024016137039190613f2f565b60408051601f198184030181529181526020820180516001600160e01b03166397e8f71760e01b1790525161373891906142be565b6000604051808303816000865af19150503d8060008114613775576040519150601f19603f3d011682016040523d82523d6000602084013e61377a565b606091505b505090508061379b5760405162461bcd60e51b8152600401610581906142d0565b505050565b60405162c7fe6f60e71b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906363ff3780906137ed9085908590600401613fbe565b602060405180830381865afa15801561380a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061382e9190614111565b1561387b5760405162461bcd60e51b815260206004820181905260248201527f534d3a206e6577206f776e65722063616e6e6f7420626520677561726469616e6044820152606401610581565b5050565b508054600082559060005260206000209081019061389d91906138a0565b50565b5b808211156138b557600081556001016138a1565b5090565b6000602082840312156138cb57600080fd5b81356001600160e01b03198116811461098b57600080fd5b6001600160a01b038116811461389d57600080fd5b60006020828403121561390a57600080fd5b813561098b816138e3565b60008060006040848603121561392a57600080fd5b8335613935816138e3565b925060208401356001600160401b038082111561395157600080fd5b818601915086601f83011261396557600080fd5b81358181111561397457600080fd5b8760208260051b850101111561398957600080fd5b6020830194508093505050509250925092565b60005b838110156139b757818101518382015260200161399f565b50506000910152565b600081518084526139d881602086016020860161399c565b601f01601f19169290920160200192915050565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b82811015613a4157603f19888603018452613a2f8583516139c0565b94509285019290850190600101613a13565b5092979650505050505050565b60008060408385031215613a6157600080fd5b8235613a6c816138e3565b946020939093013593505050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b0381118282101715613ab857613ab8613a7a565b604052919050565b60006001600160401b03821115613ad957613ad9613a7a565b50601f01601f191660200190565b600082601f830112613af857600080fd5b8135613b0b613b0682613ac0565b613a90565b818152846020838601011115613b2057600080fd5b816020850160208301376000918101602001919091529392505050565b60008060408385031215613b5057600080fd5b8235915060208301356001600160401b03811115613b6d57600080fd5b613b7985828601613ae7565b9150509250929050565b60008060408385031215613b9657600080fd5b8235613ba1816138e3565b91506020830135613bb1816138e3565b809150509250929050565b60008083601f840112613bce57600080fd5b5081356001600160401b03811115613be557600080fd5b602083019150836020828501011115613bfd57600080fd5b9250929050565b600080600060408486031215613c1957600080fd5b8335613c24816138e3565b925060208401356001600160401b03811115613c3f57600080fd5b613c4b86828701613bbc565b9497909650939450505050565b634e487b7160e01b600052602160045260246000fd5b60058110613c8c57634e487b7160e01b600052602160045260246000fd5b9052565b8281526040810161098b6020830184613c6e565b60008060008060808587031215613cba57600080fd5b8435613cc5816138e3565b93506020850135925060408501356001600160401b03811115613ce757600080fd5b613cf387828801613ae7565b949793965093946060013593505050565b60008060008060808587031215613d1a57600080fd5b8435613d25816138e3565b93506020850135925060408501356001600160401b03811115613d4757600080fd5b613d5387828801613ae7565b925050606085013560058110613d6857600080fd5b939692955090935050565b600080600060608486031215613d8857600080fd5b8335613d93816138e3565b92506020840135613da3816138e3565b91506040840135613db3816138e3565b809150509250925092565b60008060008060008060808789031215613dd757600080fd5b8635613de2816138e3565b955060208701356001600160401b0380821115613dfe57600080fd5b613e0a8a838b01613bbc565b9097509550604089013594506060890135915080821115613e2a57600080fd5b50613e3789828a01613bbc565b979a9699509497509295939492505050565b600080600060608486031215613e5e57600080fd5b8335613e69816138e3565b92506020840135613e79816138e3565b915060408401356001600160401b03811115613e9457600080fd5b613ea086828701613ae7565b9150509250925092565b600080600080600060808688031215613ec257600080fd5b8535613ecd816138e3565b945060208601356001600160401b0380821115613ee957600080fd5b613ef589838a01613bbc565b9096509450604088013593506060880135915080821115613f1557600080fd5b50613f2288828901613ae7565b9150509295509295909350565b6001600160a01b0391909116815260200190565b60008060208385031215613f5657600080fd5b82356001600160401b03811115613f6c57600080fd5b613f7885828601613bbc565b90969095509350505050565b602081016105de8284613c6e565b602080825260129082015271424d3a206d757374206265206d6f64756c6560701b604082015260600190565b6001600160a01b0392831681529116602082015260400190565b634e487b7160e01b600052603260045260246000fd5b60008235605e1983360301811261400457600080fd5b9190910192915050565b6000808335601e1984360301811261402557600080fd5b8301803591506001600160401b0382111561403f57600080fd5b602001915036819003821315613bfd57600080fd5b634e487b7160e01b600052601160045260246000fd5b60006001820161407c5761407c614054565b5060010190565b604080825283519082018190526000906020906060840190828701845b828110156140c55781516001600160a01b0316845292840192908401906001016140a0565b5050508381038285015284518082528583019183019060005b818110156141045783516001600160e01b031916835292840192918401916001016140de565b5090979650505050505050565b60006020828403121561412357600080fd5b8151801515811461098b57600080fd5b60006020828403121561414557600080fd5b815161098b816138e3565b60208082526016908201527512d34e881b595d1a1bd9081b9bdd08185b1b1bddd95960521b604082015260600190565b60006020828403121561419257600080fd5b5051919050565b6001600160f81b0319888116825287166001820152606086901b6bffffffffffffffffffffffff191660028201526016810185905283516000906141e481603685016020890161399c565b909101603681019390935250605682015260760195945050505050565b8183823760009101908152919050565b60408152600061422460408301856139c0565b90508260208301529392505050565b6020808252601690820152754b523a20496e76616c6964205369676e61747572657360501b604082015260600190565b808201808211156105de576105de614054565b818103818111156105de576105de614054565b6001600160a01b038416815282151560208201526060604082018190526000906142b5908301846139c0565b95945050505050565b6000825161400481846020870161399c565b6020808252601f908201527f534d3a2063616e63656c20616c6c206f7065726174696f6e206661696c656400604082015260600190565b6000808585111561431757600080fd5b8386111561432457600080fd5b5050820193919092039150565b634e487b7160e01b600052603160045260246000fd5b60018060a01b03841681528260208201526060604082015260006142b560608301846139c0565b60006020828403121561438057600080fd5b81516001600160401b0381111561439657600080fd5b8201601f810184136143a757600080fd5b80516143b5613b0682613ac0565b8181528560208385010111156143ca57600080fd5b6142b582602083016020860161399c56fea264697066735822122004dbc40d13974a024e6ea335b972bdb6cebc4cda1836c125728a984dbd9c723b64736f6c63430008110033000000000000000000000000bac8780b99ae84656989be9c6a0b1470417a6dc4000000000000000000000000eece51f53dda9881ae2b5edb752ad22c8c7aebd70000000000000000000000007bf09a75da7e88977150f452135ead9c90729cbd

Deployed Bytecode

0x608060405234801561001057600080fd5b506004361061019a5760003560e01c8063694c596b116100e4578063a5efb23511610092578063a5efb2351461046f578063ac419cfc14610482578063c0d91eaf14610495578063c10cab45146104a8578063cbb98bee146104bb578063ce1d3e2f146104ef578063e6c09edf1461050f578063f435f5a7146105225761019a565b8063694c596b146103ea5780636b760a94146103fd5780636c459a281461041057806371bf3af11461042357806375033f4b146104365780638a85073b1461044957806397e8f7171461045c5761019a565b80632d0335ab1161014c5780632d0335ab1461032e5780632f6c493c14610357578063304e0bb01461036a5780633b73d67f1461037d5780635ad5f3e41461039e5780635bfa1b68146103b15780635d80f160146103c457806368769fd8146103d75761019a565b806301ffc9a71461023b5780630312050614610263578063075a6444146102765780630a6dd219146102965780631626ba7e146102dc57806319a145c71461030857806325b509341461031b575b60006101dc6000368080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061053592505050565b90506001600160e01b03198116630a85bd0160e11b148061020d57506001600160e01b0319811663f23a6e6160e01b145b8061022857506001600160e01b0319811663bc197c8160e01b145b156102395760046000803760206000f35b005b61024e6102493660046138b9565b610592565b60405190151581526020015b60405180910390f35b6102396102713660046138f8565b6105e4565b610289610284366004613915565b6106c3565b60405161025a91906139ec565b6102ce6102a4366004613a4e565b6001600160a01b039190911660009081526020818152604080832093835260019093019052205490565b60405190815260200161025a565b6102ef6102ea366004613b3d565b610992565b6040516001600160e01b0319909116815260200161025a565b610239610316366004613a4e565b610a69565b61024e6103293660046138b9565b610b57565b6102ce61033c3660046138f8565b6001600160a01b031660009081526020819052604090205490565b6102396103653660046138f8565b610bde565b610239610378366004613b83565b610cb8565b61039061038b366004613c04565b610dca565b60405161025a929190613c90565b6102ce6103ac366004613ca4565b61160d565b6102396103bf3660046138f8565b61169b565b61024e6103d2366004613a4e565b611775565b6102396103e5366004613b83565b6117a1565b61024e6103f8366004613d04565b61193b565b61023961040b366004613d73565b611c59565b61024e61041e366004613dbe565b611cd1565b610239610431366004613e49565b612126565b6102396104443660046138f8565b61228c565b610239610457366004613b83565b61236b565b61023961046a3660046138f8565b612470565b61028961047d366004613915565b612598565b610239610490366004613b83565b6125ca565b6102396104a3366004613c04565b61279e565b6102396104b6366004613eaa565b612a21565b6104e27f0000000000000000000000007bf09a75da7e88977150f452135ead9c90729cbd81565b60405161025a9190613f2f565b6105026104fd366004613f43565b612b6b565b60405161025a9190613f84565b61023961051d3660046138f8565b612c74565b6102396105303660046138f8565b612d4e565b600060048251101561058a5760405162461bcd60e51b81526020600482015260196024820152780aa744092dcecc2d8d2c840cceadcc6e8d2dedca0e4caccd2f603b1b60448201526064015b60405180910390fd5b506020015190565b60006001600160e01b031982166301ffc9a760e01b14806105c357506001600160e01b03198216630271189760e51b145b806105de57506001600160e01b03198216630a85bd0160e11b145b92915050565b6105ed33612ede565b6106095760405162461bcd60e51b815260040161058190613f92565b60405163da209d5160e01b81526001600160a01b037f000000000000000000000000bac8780b99ae84656989be9c6a0b1470417a6dc4169063da209d5190610658908490600090600401613fbe565b600060405180830381600087803b15801561067257600080fd5b505af1158015610686573d6000803e3d6000fd5b5050604051600092506001600160a01b03841691507f313fbef49831f81de756df207bd6dd33dc4f5757ebd556a3375e05c1050c3aa4908390a350565b60606106ce33612ede565b6106ea5760405162461bcd60e51b815260040161058190613f92565b816000816001600160401b0381111561070557610705613a7a565b60405190808252806020026020018201604052801561072e578160200160208202803683370190505b5090506000826001600160401b0381111561074b5761074b613a7a565b604051908082528060200260200182016040528015610774578160200160208202803683370190505b50905060005b838110156108925786868281811061079457610794613fd8565b90506020028101906107a69190613fee565b6107b49060208101906138f8565b8382815181106107c6576107c6613fd8565b60200260200101906001600160a01b031690816001600160a01b0316815250506108558787838181106107fb576107fb613fd8565b905060200281019061080d9190613fee565b61081b90604081019061400e565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061053592505050565b82828151811061086757610867613fd8565b6001600160e01b0319909216602092830291909101909101528061088a8161406a565b91505061077a565b50604051634ab00efb60e01b81526001600160a01b037f000000000000000000000000eece51f53dda9881ae2b5edb752ad22c8c7aebd71690634ab00efb906108e19085908590600401614083565b602060405180830381865afa1580156108fe573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109229190614111565b61097a5760405162461bcd60e51b8152602060048201526024808201527f544d3a20416464726573736573206f722053696773206e6f7420726567697374604482015263195c995960e21b6064820152608401610581565b610985878787612eec565b93505050505b9392505050565b600081516041146109e55760405162461bcd60e51b815260206004820152601c60248201527f544d3a20696e76616c6964207369676e6174757265206c656e677468000000006044820152606401610581565b60006109f38484600061304c565b90506109ff33826131d6565b610a405760405162461bcd60e51b81526020600482015260126024820152712a269d1024b73b30b634b21039b4b3b732b960711b6044820152606401610581565b507f1626ba7e356f5979dd355a3d2bfb43e80420a480c3b854edce286a82d74968699392505050565b610a7233612ede565b610a8e5760405162461bcd60e51b815260040161058190613f92565b6040516319a145c760e01b81526001600160a01b038381166004830152602482018390527f000000000000000000000000bac8780b99ae84656989be9c6a0b1470417a6dc416906319a145c790604401600060405180830381600087803b158015610af857600080fd5b505af1158015610b0c573d6000803e3d6000fd5b50505050816001600160a01b03167fcbe22d4428901024069c2997f8626afe4fe1a1e280a8de9618d51351b9b265b782604051610b4b91815260200190565b60405180910390a25050565b60006001600160e01b03198216630b135d3f60e11b1480610b8857506001600160e01b03198216630a85bd0160e11b145b80610ba357506001600160e01b031982166301ffc9a760e01b145b80610bbe57506001600160e01b0319821663f23a6e6160e01b145b806105de57506001600160e01b0319821663bc197c8160e01b1492915050565b610be733612ede565b610c035760405162461bcd60e51b815260040161058190613f92565b604051630bdb124f60e21b81526001600160a01b037f000000000000000000000000bac8780b99ae84656989be9c6a0b1470417a6dc41690632f6c493c90610c4f908490600401613f2f565b600060405180830381600087803b158015610c6957600080fd5b505af1158015610c7d573d6000803e3d6000fd5b50506040516001600160a01b03841692507f7e6adfec7e3f286831a0200a754127c171a2da564078722cb97704741bbdb0ea9150600090a250565b610cc133612ede565b610cdd5760405162461bcd60e51b815260040161058190613f92565b604051630435586b60e11b81526000906001600160a01b037f000000000000000000000000bac8780b99ae84656989be9c6a0b1470417a6dc4169063086ab0d690610d2c908690600401613f2f565b602060405180830381865afa158015610d49573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d6d9190614133565b9050610d7a838284613255565b806001600160a01b0316836001600160a01b03167f02508c98f5b30f12e216477136240f270c87a5992a7c6d5e0b8960a9f6f6af8984604051610dbd9190613f2f565b60405180910390a3505050565b6000806000610e0e85858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061053592505050565b604051631293efbb60e21b81529091506001600160a01b037f000000000000000000000000bac8780b99ae84656989be9c6a0b1470417a6dc41690634a4fbeec90610e5d908990600401613f2f565b602060405180830381865afa158015610e7a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e9e9190614111565b15610faf576001600160e01b03198116630bdb124f60e21b1480610ed257506001600160e01b03198116630304e0bb60e41b145b80610eed57506001600160e01b0319811663e6c09edf60e01b145b610f095760405162461bcd60e51b815260040161058190614150565b633424edb160e21b6001600160e01b0319821601610faf577f000000000000000000000000eece51f53dda9881ae2b5edb752ad22c8c7aebd76001600160a01b031663e06902ea6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610f7f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fa39190614180565b60039250925050611605565b604051634f6c171d60e01b81526001600160a01b037f000000000000000000000000bac8780b99ae84656989be9c6a0b1470417a6dc41690634f6c171d90610ffb908990600401613f2f565b602060405180830381865afa158015611018573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061103c9190614111565b156110c2576001600160e01b03198116630304e0bb60e41b148061107057506001600160e01b0319811663a5efb23560e01b145b8061108b57506001600160e01b031981166301d6991160e21b145b806110a657506001600160e01b03198116630b7f436d60e31b145b6110c25760405162461bcd60e51b815260040161058190614150565b635a104dcb60e01b6001600160e01b03198216016112a057604051633b325d3760e01b81526000906001600160a01b037f000000000000000000000000bac8780b99ae84656989be9c6a0b1470417a6dc41690633b325d3790611129908a90600401613f2f565b602060405180830381865afa158015611146573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061116a9190614111565b90508061120557604051634a81d26d60e11b81526001600160a01b037f000000000000000000000000bac8780b99ae84656989be9c6a0b1470417a6dc41690639503a4da906111bd908a90600401613f2f565b602060405180830381865afa1580156111da573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111fe9190614180565b6001611295565b604051634a81d26d60e11b81526001600160a01b037f000000000000000000000000bac8780b99ae84656989be9c6a0b1470417a6dc41690639503a4da90611251908a90600401613f2f565b602060405180830381865afa15801561126e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112929190614180565b60025b935093505050611605565b633e2966ef60e21b6001600160e01b031982160161136e57604051633b325d3760e01b81526000906001600160a01b037f000000000000000000000000bac8780b99ae84656989be9c6a0b1470417a6dc41690633b325d3790611307908a90600401613f2f565b602060405180830381865afa158015611324573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113489190614111565b905080611358576000600161135d565b600060025b8160ff169150935093505050611605565b630bca0a5960e01b6001600160e01b031982160161139457600060049250925050611605565b6001600160e01b03198116630d0ed3fb60e31b14806113c357506001600160e01b03198116631add82a560e21b145b806113de57506001600160e01b031981166319a145c760e01b145b1561147c57604051634a81d26d60e11b81526001600160a01b037f000000000000000000000000bac8780b99ae84656989be9c6a0b1470417a6dc41690639503a4da9061142f908990600401613f2f565b602060405180830381865afa15801561144c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114709190614180565b60019250925050611605565b6001600160e01b031981166375033f4b60e01b14806114ab57506001600160e01b03198116630189028360e11b145b1561150e577f000000000000000000000000eece51f53dda9881ae2b5edb752ad22c8c7aebd76001600160a01b031663c15d8b966040518163ffffffff1660e01b8152600401602060405180830381865afa15801561144c573d6000803e3d6000fd5b6001600160e01b03198116638a85073b60e01b148061153d57506001600160e01b03198116632b10673f60e21b145b8061155857506001600160e01b031981166371bf3af160e01b145b1561156b57600060019250925050611605565b6001600160e01b03198116630b7f436d60e31b148061159a57506001600160e01b0319811663e6c09edf60e01b145b806115b557506001600160e01b03198116630304e0bb60e41b145b156115c857600060049250925050611605565b60405162461bcd60e51b815260206004820152601260248201527112d34e881d5b9adb9bdddb881b595d1a1bd960721b6044820152606401610581565b935093915050565b60405160009061163190601960f81b90839088908890889046908990602001614199565b60408051601f198184030181529082905280516020918201207f19457468657265756d205369676e6564204d6573736167653a0a33320000000091830191909152603c820152605c016040516020818303038152906040528051906020012090505b949350505050565b6116a433612ede565b6116c05760405162461bcd60e51b815260040161058190613f92565b604051630b7f436d60e31b81526001600160a01b037f000000000000000000000000bac8780b99ae84656989be9c6a0b1470417a6dc41690635bfa1b689061170c908490600401613f2f565b600060405180830381600087803b15801561172657600080fd5b505af115801561173a573d6000803e3d6000fd5b50506040516001600160a01b03841692507f44bcce471802f9158ee4390426e4a931d186757cc50d302f6747504c17516d129150600090a250565b6001600160a01b0391909116600090815260208181526040808320938352600190930190522054151590565b6117aa33612ede565b6117c65760405162461bcd60e51b815260040161058190613f92565b816001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611804573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118289190614133565b6001600160a01b0316816001600160a01b03160361187f5760405162461bcd60e51b815260206004820152601460248201527329a69d1024b73b30b634b21033bab0b93234b0b760611b6044820152606401610581565b604051630d0ed3fb60e31b81526001600160a01b037f000000000000000000000000bac8780b99ae84656989be9c6a0b1470417a6dc416906368769fd8906118cd9085908590600401613fbe565b600060405180830381600087803b1580156118e757600080fd5b505af11580156118fb573d6000803e3d6000fd5b50506040516001600160a01b038085169350851691507f6e60a4dea8b0048bb934b375dde93967bc9163c35c0b9d5cfe0dc1f04e5e2d9e90600090a35050565b600060418351101561194f57506000611693565b600061195d8585600061304c565b9050600083600481111561197357611973613c58565b036119f657856001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156119b6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119da9190614133565b6001600160a01b0316816001600160a01b031614915050611693565b6002836004811115611a0a57611a0a613c58565b03611aa55760405162c7fe6f60e71b81526001600160a01b037f000000000000000000000000bac8780b99ae84656989be9c6a0b1470417a6dc416906363ff378090611a5c9089908590600401613fbe565b602060405180830381865afa158015611a79573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a9d9190614111565b915050611693565b6001836004811115611ab957611ab9613c58565b1480611ad657506003836004811115611ad457611ad4613c58565b145b15611c1957604184511115611bcb576000611af38686600161304c565b60405163be546e0d60e01b81529091506001600160a01b037f000000000000000000000000bac8780b99ae84656989be9c6a0b1470417a6dc4169063be546e0d90611b44908a908690600401613fbe565b602060405180830381865afa158015611b61573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b859190614111565b8015611bc257507f0000000000000000000000007bf09a75da7e88977150f452135ead9c90729cbd6001600160a01b0316816001600160a01b0316145b92505050611693565b60405163be546e0d60e01b81526001600160a01b037f000000000000000000000000bac8780b99ae84656989be9c6a0b1470417a6dc4169063be546e0d90611a5c9089908590600401613fbe565b7f0000000000000000000000007bf09a75da7e88977150f452135ead9c90729cbd6001600160a01b0316816001600160a01b031614915050949350505050565b611c6233612ede565b611c7e5760405162461bcd60e51b815260040161058190613f92565b611c89838383613255565b826001600160a01b03167fab0ca8c1a4d3a9baa49449ec32c98bdc60c6e9ecec571ed15582b90dca7d9e298383604051611cc4929190613fbe565b60405180910390a2505050565b6000611cde87878761332b565b611d2a5760405162461bcd60e51b815260206004820152601d60248201527f4b523a20546172676574206f66205f6461746120213d205f7661756c740000006044820152606401610581565b611d5460408051608081019091528060008152600060208201819052604082015260609081015290565b6000611d61898989610dca565b83816004811115611d7457611d74613c58565b6004811115611d8557611d85613c58565b8152508192505050611dd18960008a8a8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508c925061160d915050565b60208301819052611de3908a90611775565b15611f8e576001600160a01b0389166000908152602081815260408083208583015184526001019091529020544211611e555760405162461bcd60e51b815260206004820152601460248201527312d48e88151a5b59481b9bdd08195e1c1a5c995960621b6044820152606401610581565b6001600160a01b03891660009081526020819052604090206003015415611e8657611e848983602001516133f5565b505b6040513090611e98908a908a90614201565b6000604051808303816000865af19150503d8060008114611ed5576040519150601f19603f3d011682016040523d82523d6000602084013e611eda565b606091505b506060840152151560408301819052611f305760405162461bcd60e51b815260206004820152601860248201527712d48e88125b9d195c9b985b0818d85b1b0819985a5b195960421b6044820152606401610581565b81604001511515896001600160a01b03167f7da4525a280527268ba2e963ee6c1b18f43c9507bcb1d2560f652ab17c76e90a84606001518560200151604051611f7a929190614211565b60405180910390a35060400151905061211c565b611fd689836020015187878080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250508751915061193b9050565b611ff25760405162461bcd60e51b815260040161058190614233565b611ffc89876134ec565b6120405760405162461bcd60e51b815260206004820152601560248201527412d48e88111d5c1b1a58d85d19481c995c5d595cdd605a1b6044820152606401610581565b8015611e865760006120528242614263565b6001600160a01b038b166000818152602081815260408083208883018051855260018083018552928520879055858552848452516003909101805480840182558186529385209093015592909152549192506120ad91614276565b6001600160a01b038b1660008181526020818152604080832088830180518552600290910183529281902094909455905183518581529182015290917fa738aec4c92150604d027c7e038eb5f4889db730c1b895700442dad4b90ba665910160405180910390a2600193505050505b9695505050505050565b61212f33612ede565b61214b5760405162461bcd60e51b815260040161058190613f92565b604051630bcd4ebb60e01b81526001600160a01b037f000000000000000000000000eece51f53dda9881ae2b5edb752ad22c8c7aebd71690630bcd4ebb90612197908590600401613f2f565b602060405180830381865afa1580156121b4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121d89190614111565b6122245760405162461bcd60e51b815260206004820152601c60248201527f4b4d3a206d6f64756c65206973206e6f742072656769737465726564000000006044820152606401610581565b604051632411c8f960e21b81526001600160a01b0384169063904723e4906122559085906001908690600401614289565b600060405180830381600087803b15801561226f57600080fd5b505af1158015612283573d6000803e3d6000fd5b50505050505050565b61229533612ede565b6122b15760405162461bcd60e51b815260040161058190613f92565b604051630d0ed3fb60e31b81526001600160a01b037f000000000000000000000000bac8780b99ae84656989be9c6a0b1470417a6dc416906368769fd890612300908490600090600401613fbe565b600060405180830381600087803b15801561231a57600080fd5b505af115801561232e573d6000803e3d6000fd5b5050604051600092506001600160a01b03841691507f6e60a4dea8b0048bb934b375dde93967bc9163c35c0b9d5cfe0dc1f04e5e2d9e908390a350565b61237433612ede565b6123905760405162461bcd60e51b815260040161058190613f92565b604051632ad7108960e21b81526000907f000000000000000000000000bac8780b99ae84656989be9c6a0b1470417a6dc46001600160a01b03169063ab5c4224906123df908690600401613f2f565b602060405180830381865afa1580156123fc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124209190614133565b6001600160a01b03161461187f5760405162461bcd60e51b815260206004820152601760248201527629a69d1021b0b73737ba1030b2321033bab0b93234b0b760491b6044820152606401610581565b61247933612ede565b6124955760405162461bcd60e51b815260040161058190613f92565b6001600160a01b038116600090815260208190526040812060030154905b81811015612538576001600160a01b03831660009081526020819052604081206003018054839081106124e8576124e8613fd8565b6000918252602080832091909101546001600160a01b03871683528282526040808420918452600182018352808420849055600290910190915281205550806125308161406a565b9150506124b3565b506001600160a01b03821660009081526020819052604081206125609160039091019061387f565b6040516001600160a01b038316907fcb3a402591669c34ab2f5a32672eb79a626343ceea975d0b1be66ce67298e76f90600090a25050565b60606125a333612ede565b6125bf5760405162461bcd60e51b815260040161058190613f92565b611693848484612eec565b6125d333612ede565b6125ef5760405162461bcd60e51b815260040161058190613f92565b604051630435586b60e11b81526000907f000000000000000000000000bac8780b99ae84656989be9c6a0b1470417a6dc46001600160a01b03169063086ab0d69061263e908690600401613f2f565b602060405180830381865afa15801561265b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061267f9190614133565b6001600160a01b031614801561269d57506001600160a01b03811615155b6126e25760405162461bcd60e51b8152602060048201526016602482015275534d3a2043616e6e6f7420616464207472757374656560501b6044820152606401610581565b60405163da209d5160e01b81526001600160a01b037f000000000000000000000000bac8780b99ae84656989be9c6a0b1470417a6dc4169063da209d51906127309085908590600401613fbe565b600060405180830381600087803b15801561274a57600080fd5b505af115801561275e573d6000803e3d6000fd5b50506040516001600160a01b038085169350851691507f313fbef49831f81de756df207bd6dd33dc4f5757ebd556a3375e05c1050c3aa490600090a35050565b82336001600160a01b038216146127f25760405162461bcd60e51b815260206004820152601860248201527710934e8818d85b1b195c881b5d5cdd081899481d985d5b1d60421b6044820152606401610581565b60008061280184860186613a4e565b91509150816001600160a01b0316866001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561284d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128719190614133565b6001600160a01b0316036128b95760405162461bcd60e51b815260206004820152600f60248201526e4b4d3a20496e76616c6964204b424760881b6044820152606401610581565b604051634a933b1f60e01b81526001600160a01b03871690634a933b1f906128e5903090600401613f2f565b600060405180830381600087803b1580156128ff57600080fd5b505af1158015612913573d6000803e3d6000fd5b50506040516319a145c760e01b81526001600160a01b038981166004830152602482018590527f000000000000000000000000bac8780b99ae84656989be9c6a0b1470417a6dc41692506319a145c79150604401600060405180830381600087803b15801561298157600080fd5b505af1158015612995573d6000803e3d6000fd5b5050604051634ff4b8e160e11b81526001600160a01b037f000000000000000000000000bac8780b99ae84656989be9c6a0b1470417a6dc4169250639fe971c291506129e79089908690600401613fbe565b600060405180830381600087803b158015612a0157600080fd5b505af1158015612a15573d6000803e3d6000fd5b50505050505050505050565b6000612a6786600087878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525089925061160d915050565b90506000612a9287600060405180604001604052806002815260200161060f60f31b8152508761160d565b9050612a9e8783611775565b612add5760405162461bcd60e51b815260206004820152601060248201526f096a4744092dcecc2d8d2c840d0c2e6d60831b6044820152606401610581565b6000612ae98787612b6b565b9050612af78883868461193b565b612b135760405162461bcd60e51b815260040161058190614233565b612b1d88846133f5565b50876001600160a01b03167ff9303c741b41fde5495cd4aa8eb1ff8c2912281060edd43056567cce727d627784604051612b5991815260200190565b60405180910390a25050505050505050565b600080612bad84848080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061053592505050565b90506001600160e01b03198116630d0ed3fb60e31b1480612bde57506001600160e01b031981166375033f4b60e01b145b80612bf957506001600160e01b031981166319a145c760e01b145b80612c1457506001600160e01b03198116631add82a560e21b145b80612c2f57506001600160e01b03198116630189028360e11b145b80612c4a57506001600160e01b0319811663a5efb23560e01b145b80612c6557506001600160e01b03198116630bdb124f60e21b145b156115c85760009150506105de565b612c7d33612ede565b612c995760405162461bcd60e51b815260040161058190613f92565b60405163e6c09edf60e01b81526001600160a01b037f000000000000000000000000bac8780b99ae84656989be9c6a0b1470417a6dc4169063e6c09edf90612ce5908490600401613f2f565b600060405180830381600087803b158015612cff57600080fd5b505af1158015612d13573d6000803e3d6000fd5b50506040516001600160a01b03841692507ff54453d15e2e6aee566733e6da03165ea58500408e802e05aa4e75f2408f59fe9150600090a250565b612d5733612ede565b612d735760405162461bcd60e51b815260040161058190613f92565b60405163f435f5a760e01b81526001600160a01b037f000000000000000000000000bac8780b99ae84656989be9c6a0b1470417a6dc4169063f435f5a790612dbf908490600401613f2f565b600060405180830381600087803b158015612dd957600080fd5b505af1158015612ded573d6000803e3d6000fd5b505050506000306001600160a01b031682604051602401612e0e9190613f2f565b60408051601f198184030181529181526020820180516001600160e01b03166397e8f71760e01b17905251612e4391906142be565b6000604051808303816000865af19150503d8060008114612e80576040519150601f19603f3d011682016040523d82523d6000602084013e612e85565b606091505b5050905080612ea65760405162461bcd60e51b8152600401610581906142d0565b6040516001600160a01b038316907f44427e3003a08f22cf803894075ac0297524e09e521fc1c15bc91741ce3dc15990600090a25050565b6001600160a01b0316301490565b60606000826001600160401b03811115612f0857612f08613a7a565b604051908082528060200260200182016040528015612f3b57816020015b6060815260200190600190039081612f265790505b50905060005b838110156130435761301386868684818110612f5f57612f5f613fd8565b9050602002810190612f719190613fee565b612f7f9060208101906138f8565b878785818110612f9157612f91613fd8565b9050602002810190612fa39190613fee565b60200135888886818110612fb957612fb9613fd8565b9050602002810190612fcb9190613fee565b612fd990604081019061400e565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061355792505050565b82828151811061302557613025613fd8565b6020026020010181905250808061303b9061406a565b915050612f41565b50949350505050565b6041808202830160208101516040820151919092015160009260ff9190911691601b83148061307e57508260ff16601c145b6130ca5760405162461bcd60e51b815260206004820152601b60248201527f553a2062616420762076616c756520696e207369676e617475726500000000006044820152606401610581565b6fa2a8918ca85bafe22016d0b997e4df60600160ff1b038111156131255760405162461bcd60e51b8152602060048201526012602482015271553a20496e76616c696420732076616c756560701b6044820152606401610581565b604080516000808252602082018084528a905260ff861692820192909252606081018490526080810183905260019060a0016020604051602081039080840390855afa158015613179573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166109855760405162461bcd60e51b81526020600482015260176024820152760553a2065637265636f7665722072657475726e6564203604c1b6044820152606401610581565b6000816001600160a01b0316836001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613220573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132449190614133565b6001600160a01b0316149392505050565b61325f838361367e565b604051636b8ab97d60e01b81526001600160a01b037f000000000000000000000000bac8780b99ae84656989be9c6a0b1470417a6dc41690636b8ab97d906132ab908690600401613f2f565b600060405180830381600087803b1580156132c557600080fd5b505af11580156132d9573d6000803e3d6000fd5b5050604051634ff4b8e160e11b81526001600160a01b037f000000000000000000000000bac8780b99ae84656989be9c6a0b1470417a6dc4169250639fe971c291506122559086908590600401613fbe565b600060248210156133765760405162461bcd60e51b815260206004820152601560248201527412d48e88125b9d985b1a590819185d1855985d5b1d605a1b6044820152606401610581565b6001600160a01b0384166133c05760405162461bcd60e51b815260206004820152601160248201527012d48e88125b9d985b1a59081d985d5b1d607a1b6044820152606401610581565b60006133cf8360048187614307565b8101906133dc91906138f8565b6001600160a01b03908116908616149150509392505050565b6001600160a01b0382166000908152602081815260408083208484526001808201845282852085905560028201909352908320546003820154919290919061343d9082614276565b82146134b657600060038401613454600184614276565b8154811061346457613464613fd8565b60009182526020808320909101548083526002870190915260408083208690558883528220919091556003850180549192508291859081106134a8576134a8613fd8565b600091825260209091200155505b826003018054806134c9576134c9614331565b600190038181906000526020600020016000905590556001935050505092915050565b6001600160a01b0382166000908152602081905260408120548211613513575060006105de565b608082901c61352461271043614263565b8111156135355760009150506105de565b50506001600160a01b0391909116600090815260208190526040902055600190565b60606000856001600160a01b031685858560405160240161357a93929190614347565b60408051601f198184030181529181526020820180516001600160e01b03166347b7819960e11b179052516135af91906142be565b6000604051808303816000865af19150503d80600081146135ec576040519150601f19603f3d011682016040523d82523d6000602084013e6135f1565b606091505b5092509050808015613604575060008251115b15613624578180602001905181019061361d919061436e565b9150613043565b815115613635573d6000803e3d6000fd5b806130435760405162461bcd60e51b815260206004820152601960248201527810934e881d985d5b1d081a5b9d9bdad9481c995d995c9d1959603a1b6044820152606401610581565b61368882826137a0565b6040516313af403560e01b81526001600160a01b038316906313af4035906136b4908490600401613f2f565b600060405180830381600087803b1580156136ce57600080fd5b505af11580156136e2573d6000803e3d6000fd5b505050506000306001600160a01b0316836040516024016137039190613f2f565b60408051601f198184030181529181526020820180516001600160e01b03166397e8f71760e01b1790525161373891906142be565b6000604051808303816000865af19150503d8060008114613775576040519150601f19603f3d011682016040523d82523d6000602084013e61377a565b606091505b505090508061379b5760405162461bcd60e51b8152600401610581906142d0565b505050565b60405162c7fe6f60e71b81526001600160a01b037f000000000000000000000000bac8780b99ae84656989be9c6a0b1470417a6dc416906363ff3780906137ed9085908590600401613fbe565b602060405180830381865afa15801561380a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061382e9190614111565b1561387b5760405162461bcd60e51b815260206004820181905260248201527f534d3a206e6577206f776e65722063616e6e6f7420626520677561726469616e6044820152606401610581565b5050565b508054600082559060005260206000209081019061389d91906138a0565b50565b5b808211156138b557600081556001016138a1565b5090565b6000602082840312156138cb57600080fd5b81356001600160e01b03198116811461098b57600080fd5b6001600160a01b038116811461389d57600080fd5b60006020828403121561390a57600080fd5b813561098b816138e3565b60008060006040848603121561392a57600080fd5b8335613935816138e3565b925060208401356001600160401b038082111561395157600080fd5b818601915086601f83011261396557600080fd5b81358181111561397457600080fd5b8760208260051b850101111561398957600080fd5b6020830194508093505050509250925092565b60005b838110156139b757818101518382015260200161399f565b50506000910152565b600081518084526139d881602086016020860161399c565b601f01601f19169290920160200192915050565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b82811015613a4157603f19888603018452613a2f8583516139c0565b94509285019290850190600101613a13565b5092979650505050505050565b60008060408385031215613a6157600080fd5b8235613a6c816138e3565b946020939093013593505050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b0381118282101715613ab857613ab8613a7a565b604052919050565b60006001600160401b03821115613ad957613ad9613a7a565b50601f01601f191660200190565b600082601f830112613af857600080fd5b8135613b0b613b0682613ac0565b613a90565b818152846020838601011115613b2057600080fd5b816020850160208301376000918101602001919091529392505050565b60008060408385031215613b5057600080fd5b8235915060208301356001600160401b03811115613b6d57600080fd5b613b7985828601613ae7565b9150509250929050565b60008060408385031215613b9657600080fd5b8235613ba1816138e3565b91506020830135613bb1816138e3565b809150509250929050565b60008083601f840112613bce57600080fd5b5081356001600160401b03811115613be557600080fd5b602083019150836020828501011115613bfd57600080fd5b9250929050565b600080600060408486031215613c1957600080fd5b8335613c24816138e3565b925060208401356001600160401b03811115613c3f57600080fd5b613c4b86828701613bbc565b9497909650939450505050565b634e487b7160e01b600052602160045260246000fd5b60058110613c8c57634e487b7160e01b600052602160045260246000fd5b9052565b8281526040810161098b6020830184613c6e565b60008060008060808587031215613cba57600080fd5b8435613cc5816138e3565b93506020850135925060408501356001600160401b03811115613ce757600080fd5b613cf387828801613ae7565b949793965093946060013593505050565b60008060008060808587031215613d1a57600080fd5b8435613d25816138e3565b93506020850135925060408501356001600160401b03811115613d4757600080fd5b613d5387828801613ae7565b925050606085013560058110613d6857600080fd5b939692955090935050565b600080600060608486031215613d8857600080fd5b8335613d93816138e3565b92506020840135613da3816138e3565b91506040840135613db3816138e3565b809150509250925092565b60008060008060008060808789031215613dd757600080fd5b8635613de2816138e3565b955060208701356001600160401b0380821115613dfe57600080fd5b613e0a8a838b01613bbc565b9097509550604089013594506060890135915080821115613e2a57600080fd5b50613e3789828a01613bbc565b979a9699509497509295939492505050565b600080600060608486031215613e5e57600080fd5b8335613e69816138e3565b92506020840135613e79816138e3565b915060408401356001600160401b03811115613e9457600080fd5b613ea086828701613ae7565b9150509250925092565b600080600080600060808688031215613ec257600080fd5b8535613ecd816138e3565b945060208601356001600160401b0380821115613ee957600080fd5b613ef589838a01613bbc565b9096509450604088013593506060880135915080821115613f1557600080fd5b50613f2288828901613ae7565b9150509295509295909350565b6001600160a01b0391909116815260200190565b60008060208385031215613f5657600080fd5b82356001600160401b03811115613f6c57600080fd5b613f7885828601613bbc565b90969095509350505050565b602081016105de8284613c6e565b602080825260129082015271424d3a206d757374206265206d6f64756c6560701b604082015260600190565b6001600160a01b0392831681529116602082015260400190565b634e487b7160e01b600052603260045260246000fd5b60008235605e1983360301811261400457600080fd5b9190910192915050565b6000808335601e1984360301811261402557600080fd5b8301803591506001600160401b0382111561403f57600080fd5b602001915036819003821315613bfd57600080fd5b634e487b7160e01b600052601160045260246000fd5b60006001820161407c5761407c614054565b5060010190565b604080825283519082018190526000906020906060840190828701845b828110156140c55781516001600160a01b0316845292840192908401906001016140a0565b5050508381038285015284518082528583019183019060005b818110156141045783516001600160e01b031916835292840192918401916001016140de565b5090979650505050505050565b60006020828403121561412357600080fd5b8151801515811461098b57600080fd5b60006020828403121561414557600080fd5b815161098b816138e3565b60208082526016908201527512d34e881b595d1a1bd9081b9bdd08185b1b1bddd95960521b604082015260600190565b60006020828403121561419257600080fd5b5051919050565b6001600160f81b0319888116825287166001820152606086901b6bffffffffffffffffffffffff191660028201526016810185905283516000906141e481603685016020890161399c565b909101603681019390935250605682015260760195945050505050565b8183823760009101908152919050565b60408152600061422460408301856139c0565b90508260208301529392505050565b6020808252601690820152754b523a20496e76616c6964205369676e61747572657360501b604082015260600190565b808201808211156105de576105de614054565b818103818111156105de576105de614054565b6001600160a01b038416815282151560208201526060604082018190526000906142b5908301846139c0565b95945050505050565b6000825161400481846020870161399c565b6020808252601f908201527f534d3a2063616e63656c20616c6c206f7065726174696f6e206661696c656400604082015260600190565b6000808585111561431757600080fd5b8386111561432457600080fd5b5050820193919092039150565b634e487b7160e01b600052603160045260246000fd5b60018060a01b03841681528260208201526060604082015260006142b560608301846139c0565b60006020828403121561438057600080fd5b81516001600160401b0381111561439657600080fd5b8201601f810184136143a757600080fd5b80516143b5613b0682613ac0565b8181528560208385010111156143ca57600080fd5b6142b582602083016020860161399c56fea264697066735822122004dbc40d13974a024e6ea335b972bdb6cebc4cda1836c125728a984dbd9c723b64736f6c63430008110033

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

000000000000000000000000bac8780b99ae84656989be9c6a0b1470417a6dc4000000000000000000000000eece51f53dda9881ae2b5edb752ad22c8c7aebd70000000000000000000000007bf09a75da7e88977150f452135ead9c90729cbd

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

-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 000000000000000000000000bac8780b99ae84656989be9c6a0b1470417a6dc4
Arg [1] : 000000000000000000000000eece51f53dda9881ae2b5edb752ad22c8c7aebd7
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
[ 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.