Contract Address Details

0x035eedecAe123d87C1a40DE656d3BB3dEb9AbDF2

Contract Name
MultisigAurumOracle
Creator
0x67a45f–3fe76a at 0x0ca2cd–a0fa49
Balance
0 REI
Tokens
Fetching tokens...
Transactions
132,572 Transactions
Transfers
0 Transfers
Gas Used
10,724,463,234
Last Balance Update
194099
Contract name:
MultisigAurumOracle




Optimization enabled
false
Compiler version
v0.8.12+commit.f00d7308




EVM Version
default




Verified at
2022-04-30T07:08:21.614712Z

Constructor Arguments

000000000000000000000000296b37e90c3ae5ed49528b0d7c1f1aa163a251ea00000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000300000000000000000000000067a45f2f461a3d70585066e64660abc3943fe76a000000000000000000000000acd79822d3276ebd0c1fd29336dec880b8a393a7000000000000000000000000a40cf5594e3d1462a3d2dd7d29e08e24b9294a09

Arg [0] (address) : 0x296b37e90c3ae5ed49528b0d7c1f1aa163a251ea
Arg [1] (address[]) : [0x67a45f2f461a3d70585066e64660abc3943fe76a, 0xacd79822d3276ebd0c1fd29336dec880b8a393a7, 0xa40cf5594e3d1462a3d2dd7d29e08e24b9294a09]
Arg [2] (uint8) : 2

              

Contract source code

// File: src\contracts\interface\ComptrollerInterface.sol

// SPDX-License-Identifier: MIT
pragma solidity 0.8.12;

interface ComptrollerInterface {
    function isComptroller() external pure returns(bool);
    function isProtocolPaused() external view returns(bool);
    function getMintedGOLDs(address) external view returns(uint);
    function getComptrollerOracleAddress() external view returns(address);
    function getGoldMintRate() external view returns (uint);
    /*** Assets You Are In ***/

    function getAssetsIn(address) external view returns(LendTokenInterface[] memory);
    function exitMarket(address lendToken) external;

    /*** Policy Hooks ***/

    function mintAllowed(address lendToken, address minter) external;
    function redeemAllowed(address lendToken, address redeemer, uint redeemTokens) external;
    function borrowAllowed(address lendToken, address borrower, uint borrowAmount) external;
    function repayBorrowAllowed(address lendToken, address borrower) external;
    function liquidateBorrowAllowed(address lendTokenBorrowed, address lendTokenCollateral, address borrower, uint repayAmount) external;
    function seizeAllowed(address lendTokenCollateral, address lendTokenBorrowed, address liquidator, address borrower) external;
    function transferAllowed(address lendToken, address src, address dst, uint transferTokens) external;

    /*** Liquidity/Liquidation Calculations ***/

    function liquidateCalculateSeizeTokens(
        address lendTokenBorrowed,
        address lendTokenCollateral,
        uint repayAmount) external view returns (uint);
    function setMintedGOLDOf(address owner, uint amount) external;


    function liquidateGOLDCalculateSeizeTokens(
        address lendTokenCollateral,
        uint repayAmount) external view returns (uint);
}

interface ComptrollerStorageInterface {
    function getAllMarkets() external view returns(LendTokenInterface[] memory);
}
interface IComptroller {
    function liquidationIncentiveMantissa() external view returns (uint);
    /*** Treasury Data ***/
    function treasuryAddress() external view returns (address);
    function treasuryPercent() external view returns (uint);
}

interface LendTokenInterface{

    function comptroller() external view returns(ComptrollerInterface);
    function totalSupply() external view returns(uint);
    function totalBorrows() external view returns(uint);
    function borrowIndex() external view returns(uint);
    function symbol() external view returns(string memory);
    function underlying() external view returns(address);
    function isLendToken() external pure returns(bool);
    function accrualTimestamp() external view returns(uint);
    
    function getAccountBorrows(address user) external view returns(uint, uint);
    function getBorrowAddress() external view returns(address[] memory);
    
    function transfer(address dst, uint256 amount) external;
    function transferFrom(address src, address dst, uint256 amount) external;
    function approve(address spender, uint256 amount) external;
    function allowance(address owner, address spender) external view returns (uint256);
    function balanceOf(address owner) external view returns (uint256); 
    function balanceOfUnderlying(address owner) external returns (uint);
    function getAccountSnapshot(address account) external view returns (uint, uint, uint); 
    function borrowBalanceStored(address account) external view returns (uint);
    function exchangeRateStored() external view returns (uint);
    function getCash() external view returns (uint);
    function accrueInterest() external;
    function borrowRatePerSeconds() external view returns (uint);
    function supplyRatePerSeconds() external view returns (uint); 
    function exchangeRateCurrent() external returns (uint);


    function mint(uint mintAmount) external returns(uint);
    function redeem(uint redeemTokens) external;
    function redeemUnderlying(uint redeemAmount) external;
    function borrow(uint borrowAmount) external;
    function repayBorrow(uint repayAmount) external returns (uint);
    function liquidateBorrow(address borrower, uint repayAmount, LendTokenInterface lendTokenCollateral) external returns (uint);
    function seize(address liquidator, address borrower, uint seizeTokens) external;

    /*** Admin Functions ***/

}

interface PriceOracle {
    function isPriceOracle() external view returns (bool);
    function getGoldPrice() external view returns (uint);
    function getUnderlyingPrice(LendTokenInterface lendToken) external view returns (uint);
    function assetPrices(address asset) external view returns (uint);
}

interface AurumControllerInterface {

    function getGoldMinter() external view returns(address[] memory);
    function mintGOLD(uint mintGOLDAmount) external;
    function repayGOLD(uint repayGOLDAmount) external returns(uint);
    function liquidateGOLD(address borrower, uint repayAmount, LendTokenInterface lendTokenCollateral) external returns(uint);
    function getMintableGOLD(address minter) external view returns (uint);

}
interface InterestRateModel {

    function isInterestRateModel() external view returns(bool);
    function getBorrowRate(uint cash, uint borrows, uint reserves) external view returns (uint);
    
    function getSupplyRate(uint cash, uint borrows, uint reserves, uint reserveFactorMantissa) external view returns (uint);

}

// File: src\contracts\interface\ISlidingWindow.sol

// SPDX-License-Identifier: MIT
pragma solidity 0.8.12;

interface ISlidingWindow {

    struct Observation {
        uint timestamp;
        uint price0Cumulative;
        uint price1Cumulative;
    }

    function factory() external view returns(address);
    function windowSize() external view returns(uint);
    function granularity() external view returns(uint8);
    function periodSize() external view returns(uint);

    function observationIndexOf(uint timestamp) external view returns (uint8 index);

    function update(address tokenA, address tokenB) external; //Update price of pair tokens

    function consult(address tokenIn, uint amountIn, address tokenOut) external view returns (uint);  //get the price of tokenIn to tokenOut

}

// File: src\contracts\interface\IAurumOracleCentralized.sol

// SPDX-License-Identifier: MIT
pragma solidity 0.8.12;
interface IAurumOracleCentralized is PriceOracle {
    
    function isPriceOracle() external pure returns (bool);

    function initializedAsset(address token, uint128 price) external;
    function initializedGold(uint128 price) external;
    function updateAssetPrice(address token, uint128 price) external;
    function updateAssetPriceFromWindow(address token) external;
    function updateGoldPrice(uint128 price) external;
    function getGoldPrice() external view returns (uint);
    function getUnderlyingPrice(LendTokenInterface lendToken) external view returns (uint);
    function assetPrices(address token) external view returns (uint);

}

// File: src\contracts\MultisigAurumOracle.sol

// SPDX-License-Identifier: MIT
pragma solidity 0.8.12;
contract MultisigAurumOracle {

    event Submit(uint indexed txId);
    event Approve(uint indexed txId, address indexed approveBy);
    event Reject(uint indexed txId, address indexed revokeBy);
    event Execute(uint indexed txId);

    struct Transaction {
        address token;
        uint128 price;
        uint8 callswitch; // this will trigger different function, 0 = updateAssetPrice, 1 = updateAssetPriceFromWindow, 2 = updateGoldPrice
        bool executed;
        uint expireTimestamp; // set expire time, in case the system fetch multiple submit, first submit can be execute others will expire before reach the period time
    }
    Transaction[] public transactions;

    IAurumOracleCentralized public oracle;
    address[] public owners;
    mapping(address => bool) public isOwner;
    uint8 public required; // Amount of approve wallet to execute transaction
    mapping (uint => mapping(address => bool)) public approved; //[transaction][owner] => boolean
    mapping (uint => mapping(address => bool)) public voted; //[transaction][owner] => boolean


    constructor (address oracle_, address[] memory owners_, uint8 required_) {
        require(owners_.length > 0, "owners invalid");
        require(required_ > 0 && required_ <= owners_.length, "required invalid");

        oracle = IAurumOracleCentralized(oracle_);
        
        for(uint i; i< owners_.length; i++){
            address owner = owners_[i];

            require (owner != address(0), "owner is address 0");
            require (!isOwner[owner], "owner is not unique");

            isOwner[owner] = true;
            owners.push(owner);
        }

        required = required_;
    }

    modifier onlyOwner {
        require(isOwner[msg.sender], "only owner");
        _;
    }

    modifier txExists(uint txId_){
        require (txId_ < transactions.length, "tx does not exist");
        _;
    }
    modifier notVoted(uint txId_){
        require (!voted[txId_][msg.sender], "tx already approved");
        _;
    }
    modifier notExecuted(uint txId_){
        require (!transactions[txId_].executed, "tx already executed");
        _;
    }

    modifier notExpire(uint txId_){
        require (transactions[txId_].expireTimestamp >= block.timestamp, "tx expired");
        _;
    }

    function submit(address token_, uint128 price_, uint8 callswitch_) external onlyOwner{
        uint expire = block.timestamp + 10 minutes; // set expire time of the transaction = 10 minutes
        //Create new transaction waiting others to confirm.
        transactions.push(
            Transaction({
                token: token_,
                price: price_,
                callswitch: callswitch_,
                executed: false,
                expireTimestamp: expire
            })
        );
        emit Submit(transactions.length -1); //emit the recent transaction.
    }

    //Approve function is to vote approve to the transaction
    function approve(uint txId_) external onlyOwner txExists(txId_) notVoted(txId_) notExecuted(txId_) notExpire(txId_) {
        approved[txId_][msg.sender] = true; //Vote approve
        voted[txId_][msg.sender] = true;
        emit Approve(txId_, msg.sender);
    }

    //Reject function is to vote reject to the transaction
    function reject(uint txId_) external onlyOwner txExists(txId_) notVoted(txId_) notExecuted(txId_) notExpire(txId_) {
        approved[txId_][msg.sender] = false; //Vote reject
        voted[txId_][msg.sender] = true;
        emit Reject(txId_, msg.sender);
    }

    //This will count approve
    function getApprovalCount(uint txId_) public view returns (uint){
        uint count;
        for(uint i; i< owners.length; i++){
            if (approved[txId_][owners[i]]){
                count += 1;
            }
        }
        return count;
    }

    function execute(uint txId_) external txExists(txId_) notExecuted(txId_) notExpire(txId_) {
        require(getApprovalCount(txId_) >= required, "approvals < required"); //Whenever the signer approve reach 'required' the tx. can be executed by anyone
        Transaction storage transaction = transactions[txId_];
        transaction.executed = true; // This will also prevent reentrance


        uint8 callswitch = transaction.callswitch; //gas optimizer

        if(callswitch == 0) {
            oracle.updateAssetPrice(transaction.token, transaction.price);
            emit Execute(txId_);
            return; //Short circuit out
        }
        if(callswitch == 1) {
            oracle.updateAssetPriceFromWindow(transaction.token);
            emit Execute(txId_);
            return; //Short circuit out
        }
        if(callswitch == 2) {
            oracle.updateGoldPrice(transaction.price);
            emit Execute(txId_);
            return; //Short circuit out
        }
    }
}
        

Contract ABI

[{"type":"constructor","stateMutability":"nonpayable","inputs":[{"type":"address","name":"oracle_","internalType":"address"},{"type":"address[]","name":"owners_","internalType":"address[]"},{"type":"uint8","name":"required_","internalType":"uint8"}]},{"type":"event","name":"Approve","inputs":[{"type":"uint256","name":"txId","internalType":"uint256","indexed":true},{"type":"address","name":"approveBy","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"Execute","inputs":[{"type":"uint256","name":"txId","internalType":"uint256","indexed":true}],"anonymous":false},{"type":"event","name":"Reject","inputs":[{"type":"uint256","name":"txId","internalType":"uint256","indexed":true},{"type":"address","name":"revokeBy","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"Submit","inputs":[{"type":"uint256","name":"txId","internalType":"uint256","indexed":true}],"anonymous":false},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"approve","inputs":[{"type":"uint256","name":"txId_","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"approved","inputs":[{"type":"uint256","name":"","internalType":"uint256"},{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"execute","inputs":[{"type":"uint256","name":"txId_","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getApprovalCount","inputs":[{"type":"uint256","name":"txId_","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"isOwner","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract IAurumOracleCentralized"}],"name":"oracle","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"owners","inputs":[{"type":"uint256","name":"","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"reject","inputs":[{"type":"uint256","name":"txId_","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint8","name":"","internalType":"uint8"}],"name":"required","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"submit","inputs":[{"type":"address","name":"token_","internalType":"address"},{"type":"uint128","name":"price_","internalType":"uint128"},{"type":"uint8","name":"callswitch_","internalType":"uint8"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"token","internalType":"address"},{"type":"uint128","name":"price","internalType":"uint128"},{"type":"uint8","name":"callswitch","internalType":"uint8"},{"type":"bool","name":"executed","internalType":"bool"},{"type":"uint256","name":"expireTimestamp","internalType":"uint256"}],"name":"transactions","inputs":[{"type":"uint256","name":"","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"voted","inputs":[{"type":"uint256","name":"","internalType":"uint256"},{"type":"address","name":"","internalType":"address"}]}]
            

Deployed ByteCode

0x608060405234801561001057600080fd5b50600436106100b45760003560e01c8063b759f95411610071578063b759f954146101cb578063b8adaa11146101e7578063ba7e7cab14610203578063c7fb34b614610233578063dc8452cd1461024f578063fe0d94c11461026d576100b4565b8063025e7c27146100b95780632f54bf6e146100e95780635277b4ae146101195780637dc0d1d0146101495780638253951a146101675780639ace38c214610197575b600080fd5b6100d360048036038101906100ce919061131a565b610289565b6040516100e09190611388565b60405180910390f35b61010360048036038101906100fe91906113cf565b6102c8565b6040516101109190611417565b60405180910390f35b610133600480360381019061012e9190611432565b6102e8565b6040516101409190611417565b60405180910390f35b610151610317565b60405161015e91906114d1565b60405180910390f35b610181600480360381019061017c9190611432565b61033d565b60405161018e9190611417565b60405180910390f35b6101b160048036038101906101ac919061131a565b61036c565b6040516101c2959493929190611542565b60405180910390f35b6101e560048036038101906101e0919061131a565b610408565b005b61020160048036038101906101fc919061131a565b610775565b005b61021d6004803603810190610218919061131a565b610ae2565b60405161022a9190611595565b60405180910390f35b61024d60048036038101906102489190611608565b610bc3565b005b610257610df8565b604051610264919061165b565b60405180910390f35b6102876004803603810190610282919061131a565b610e0b565b005b6002818154811061029957600080fd5b906000526020600020016000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60036020528060005260406000206000915054906101000a900460ff1681565b60066020528160005260406000206020528060005260406000206000915091509054906101000a900460ff1681565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60056020528160005260406000206020528060005260406000206000915091509054906101000a900460ff1681565b6000818154811061037c57600080fd5b90600052602060002090600302016000915090508060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060010160009054906101000a90046fffffffffffffffffffffffffffffffff16908060010160109054906101000a900460ff16908060010160119054906101000a900460ff16908060020154905085565b600360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16610494576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161048b906116d3565b60405180910390fd5b8060008054905081106104dc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104d39061173f565b60405180910390fd5b816006600082815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161561057b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610572906117ab565b60405180910390fd5b82600081815481106105905761058f6117cb565b5b906000526020600020906003020160010160119054906101000a900460ff16156105ef576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105e690611846565b60405180910390fd5b834260008281548110610605576106046117cb565b5b9060005260206000209060030201600201541015610658576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161064f906118b2565b60405180910390fd5b60016005600087815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555060016006600087815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055503373ffffffffffffffffffffffffffffffffffffffff16857f47ad3e4b0f4bdbe3ac08708bbc45053d2ff616911b39e65563fd9bd78190964560405160405180910390a35050505050565b600360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16610801576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107f8906116d3565b60405180910390fd5b806000805490508110610849576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108409061173f565b60405180910390fd5b816006600082815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16156108e8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108df906117ab565b60405180910390fd5b82600081815481106108fd576108fc6117cb565b5b906000526020600020906003020160010160119054906101000a900460ff161561095c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161095390611846565b60405180910390fd5b834260008281548110610972576109716117cb565b5b90600052602060002090600302016002015410156109c5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109bc906118b2565b60405180910390fd5b60006005600087815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555060016006600087815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055503373ffffffffffffffffffffffffffffffffffffffff16857f46990193a9a78111f65f212c735737818b2632d7fd365109873b1e8f3346997360405160405180910390a35050505050565b60008060005b600280549050811015610bb95760056000858152602001908152602001600020600060028381548110610b1e57610b1d6117cb565b5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615610ba657600182610ba39190611901565b91505b8080610bb190611957565b915050610ae8565b5080915050919050565b600360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16610c4f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c46906116d3565b60405180910390fd5b600061025842610c5f9190611901565b905060006040518060a001604052808673ffffffffffffffffffffffffffffffffffffffff168152602001856fffffffffffffffffffffffffffffffff1681526020018460ff16815260200160001515815260200183815250908060018154018082558091505060019003906000526020600020906003020160009091909190915060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060208201518160010160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555060408201518160010160106101000a81548160ff021916908360ff16021790555060608201518160010160116101000a81548160ff0219169083151502179055506080820151816002015550506001600080549050610dc691906119a0565b7f08324b3d745b914e3abd4ffbfead91e3b78391a98c173202129215ab933adfbe60405160405180910390a250505050565b600460009054906101000a900460ff1681565b806000805490508110610e53576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e4a9061173f565b60405180910390fd5b8160008181548110610e6857610e676117cb565b5b906000526020600020906003020160010160119054906101000a900460ff1615610ec7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ebe90611846565b60405180910390fd5b824260008281548110610edd57610edc6117cb565b5b9060005260206000209060030201600201541015610f30576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f27906118b2565b60405180910390fd5b600460009054906101000a900460ff1660ff16610f4c85610ae2565b1015610f8d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f8490611a20565b60405180910390fd5b6000808581548110610fa257610fa16117cb565b5b9060005260206000209060030201905060018160010160116101000a81548160ff02191690831515021790555060008160010160109054906101000a900460ff16905060008160ff1614156110f857600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166371232b1b8360000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff168460010160009054906101000a90046fffffffffffffffffffffffffffffffff166040518363ffffffff1660e01b8152600401611092929190611a40565b600060405180830381600087803b1580156110ac57600080fd5b505af11580156110c0573d6000803e3d6000fd5b50505050857fddb556f1d2c1ec821e910b019d3685b229db152a0ecd517ca7e24b8bd713928960405160405180910390a250506112d9565b60018160ff1614156111e957600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636b7f0bd78360000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040518263ffffffff1660e01b81526004016111839190611388565b600060405180830381600087803b15801561119d57600080fd5b505af11580156111b1573d6000803e3d6000fd5b50505050857fddb556f1d2c1ec821e910b019d3685b229db152a0ecd517ca7e24b8bd713928960405160405180910390a250506112d9565b60028160ff1614156112d657600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16634b1386c98360010160009054906101000a90046fffffffffffffffffffffffffffffffff166040518263ffffffff1660e01b81526004016112709190611a69565b600060405180830381600087803b15801561128a57600080fd5b505af115801561129e573d6000803e3d6000fd5b50505050857fddb556f1d2c1ec821e910b019d3685b229db152a0ecd517ca7e24b8bd713928960405160405180910390a250506112d9565b50505b50505050565b600080fd5b6000819050919050565b6112f7816112e4565b811461130257600080fd5b50565b600081359050611314816112ee565b92915050565b6000602082840312156113305761132f6112df565b5b600061133e84828501611305565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061137282611347565b9050919050565b61138281611367565b82525050565b600060208201905061139d6000830184611379565b92915050565b6113ac81611367565b81146113b757600080fd5b50565b6000813590506113c9816113a3565b92915050565b6000602082840312156113e5576113e46112df565b5b60006113f3848285016113ba565b91505092915050565b60008115159050919050565b611411816113fc565b82525050565b600060208201905061142c6000830184611408565b92915050565b60008060408385031215611449576114486112df565b5b600061145785828601611305565b9250506020611468858286016113ba565b9150509250929050565b6000819050919050565b600061149761149261148d84611347565b611472565b611347565b9050919050565b60006114a98261147c565b9050919050565b60006114bb8261149e565b9050919050565b6114cb816114b0565b82525050565b60006020820190506114e660008301846114c2565b92915050565b60006fffffffffffffffffffffffffffffffff82169050919050565b611511816114ec565b82525050565b600060ff82169050919050565b61152d81611517565b82525050565b61153c816112e4565b82525050565b600060a0820190506115576000830188611379565b6115646020830187611508565b6115716040830186611524565b61157e6060830185611408565b61158b6080830184611533565b9695505050505050565b60006020820190506115aa6000830184611533565b92915050565b6115b9816114ec565b81146115c457600080fd5b50565b6000813590506115d6816115b0565b92915050565b6115e581611517565b81146115f057600080fd5b50565b600081359050611602816115dc565b92915050565b600080600060608486031215611621576116206112df565b5b600061162f868287016113ba565b9350506020611640868287016115c7565b9250506040611651868287016115f3565b9150509250925092565b60006020820190506116706000830184611524565b92915050565b600082825260208201905092915050565b7f6f6e6c79206f776e657200000000000000000000000000000000000000000000600082015250565b60006116bd600a83611676565b91506116c882611687565b602082019050919050565b600060208201905081810360008301526116ec816116b0565b9050919050565b7f747820646f6573206e6f74206578697374000000000000000000000000000000600082015250565b6000611729601183611676565b9150611734826116f3565b602082019050919050565b600060208201905081810360008301526117588161171c565b9050919050565b7f747820616c726561647920617070726f76656400000000000000000000000000600082015250565b6000611795601383611676565b91506117a08261175f565b602082019050919050565b600060208201905081810360008301526117c481611788565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f747820616c726561647920657865637574656400000000000000000000000000600082015250565b6000611830601383611676565b915061183b826117fa565b602082019050919050565b6000602082019050818103600083015261185f81611823565b9050919050565b7f7478206578706972656400000000000000000000000000000000000000000000600082015250565b600061189c600a83611676565b91506118a782611866565b602082019050919050565b600060208201905081810360008301526118cb8161188f565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061190c826112e4565b9150611917836112e4565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0382111561194c5761194b6118d2565b5b828201905092915050565b6000611962826112e4565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415611995576119946118d2565b5b600182019050919050565b60006119ab826112e4565b91506119b6836112e4565b9250828210156119c9576119c86118d2565b5b828203905092915050565b7f617070726f76616c73203c207265717569726564000000000000000000000000600082015250565b6000611a0a601483611676565b9150611a15826119d4565b602082019050919050565b60006020820190508181036000830152611a39816119fd565b9050919050565b6000604082019050611a556000830185611379565b611a626020830184611508565b9392505050565b6000602082019050611a7e6000830184611508565b9291505056fea2646970667358221220a3a25048c1156125b152173cf389d40a981f18642de712c381c7d7217e6964b164736f6c634300080c0033