Address Details
contract

0x2c116311F91F5Da1f5E0563402ac1f0882587dEA

Contract Name
StakedGrantManager
Creator
0xe1c46d–097af5 at 0xbad177–5fa4b0
Balance
0 CELO ( )
Locked CELO Balance
0.00 CELO
Voting CELO Balance
0.00 CELO
Pending Unlocked Gold
0.00 CELO
Tokens
Fetching tokens...
Transactions
1 Transactions
Transfers
0 Transfers
Gas Used
111,845
Last Balance Update
14695782
This contract has been partially verified via Sourcify. View contract in Sourcify repository
Contract name:
StakedGrantManager




Optimization enabled
true
Compiler version
v0.8.11+commit.d7f03943




Optimization runs
200
EVM Version
london




Verified at
2022-08-22T05:34:02.697468Z

src/grants/StakedGrantManager.sol

// SPDX-License-Identifier: Apache-2.0
// https://docs.soliditylang.org/en/v0.8.10/style-guide.html
pragma solidity ^0.8.10;

import "lib/forge-std/src/console.sol";
import {IERC20} from "lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol";
import {PausableUpgradeable} from "lib/openzeppelin-contracts-upgradeable/contracts/security/PausableUpgradeable.sol";
import {OwnableUpgradeable} from "lib/openzeppelin-contracts-upgradeable/contracts/access/OwnableUpgradeable.sol";
import {ReentrancyGuardUpgradeable} from "lib/openzeppelin-contracts-upgradeable/contracts/security/ReentrancyGuardUpgradeable.sol";
import {ImpactVault} from "src/grants/ImpactVault.sol";
import {ImpactVaultManager} from "src/grants/ImpactVaultManager.sol";
import {SpiralsRegistry} from "src/grants/SpiralsRegistry.sol";
import {IRegistry} from "src/interfaces/IRegistry.sol";
import {IManager} from "src/interfaces/IManager.sol";
import {SafeERC20} from "lib/openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol";

struct StakedGrant {
    ImpactVault ownerVault;
    ImpactVault beneficiaryVault;
    mapping(address => StakedGrantToken) tokens;
}

struct StakedGrantToken {
    uint256 allocated; // total approved for grantee
    uint256 disbursed;
}

/// @title StakedGrantManager
///
/// @author @douglasqian
contract StakedGrantManager is
    OwnableUpgradeable,
    PausableUpgradeable,
    ReentrancyGuardUpgradeable
{
    using SafeERC20 for IERC20;

    /*
     * EVENTS
     */
    event StakedGrantCreated(
        bytes32 indexed id,
        address indexed ownerVault,
        address indexed beneficiaryVault,
        uint96 _externalGrantId
    );
    event StakedGrantFunded(
        bytes32 indexed id,
        address indexed token,
        uint256 amount
    );
    event StakedFundsDisbursed(
        bytes32 indexed id,
        address indexed token,
        uint256 amount
    );
    event DependenciesUpdated(address spiralsRegistry);

    /*
     * STATE VARIABLES
     */
    SpiralsRegistry public c_spiralsRegistry;
    // keccak256(ownerVault, beneficiaryVault) -> info
    mapping(bytes32 => StakedGrant) internal grants;

    /*
     * INITIALIZERS
     */
    constructor() {}

    function initialize(address _registryAddress) external initializer {
        __Ownable_init();
        __Pausable_init();
        __ReentrancyGuard_init();
        // Ensures that `_owner` is set.
        setDependencies(_registryAddress);
    }

    function setDependencies(address _registryAddress)
        public
        onlyOwner
        whenNotPaused
    {
        c_spiralsRegistry = SpiralsRegistry(_registryAddress);
        emit DependenciesUpdated(_registryAddress);
    }

    /*
     * CREATE
     */
    function createGrant(address _beneficiary, uint96 _externalGrantId)
        external
        whenNotPaused
        returns (bytes32 id)
    {
        // Get ImpactVault addresses for owner & beneficiary.
        // Create them if they don't exist yet.
        ImpactVaultManager vaultMgr = getImpactVaultManager();
        address _owner = msg.sender;

        bytes32 ownerVaultId = vaultMgr.getOwnerVaultId(_owner, _beneficiary);
        ImpactVault ownerVault = vaultMgr._getVault(ownerVaultId);

        if (address(ownerVault) == address(0)) {
            ownerVault = vaultMgr.createOwnerVault(_owner, _beneficiary);
        }
        bytes32 beneficiaryVaultId = vaultMgr.getBeneficiaryVaultId(
            _beneficiary
        );
        ImpactVault beneficiaryVault = vaultMgr._getVault(beneficiaryVaultId);
        if (address(beneficiaryVault) == address(0)) {
            beneficiaryVault = vaultMgr.createBeneficiaryVault(_beneficiary);
        }
        id = _getGrantId(address(ownerVault), address(beneficiaryVault));

        StakedGrant storage grant = grants[id];
        grant.ownerVault = ownerVault;
        grant.beneficiaryVault = beneficiaryVault;

        emit StakedGrantCreated(
            id,
            address(ownerVault),
            address(beneficiaryVault),
            _externalGrantId
        );
    }

    /*
     * FUND
     */
    function fundGrant(
        bytes32 _id,
        address _token,
        uint256 _amount
    ) external payable whenNotPaused {
        StakedGrant storage grant = grants[_id];
        require(
            address(grant.ownerVault) != address(0),
            "GRANT_NOT_CREATED_YET"
        );
        IERC20(_token).transferFrom(
            msg.sender,
            address(grant.ownerVault),
            _amount
        );
        grant.ownerVault.stake(_token, _amount);
        grant.tokens[_token].allocated += _amount;

        emit StakedGrantFunded(_id, _token, _amount);
    }

    function disburseFunds(
        bytes32 _id,
        address _token,
        uint256 _amount
    ) external whenNotPaused {
        StakedGrant storage grant = grants[_id];
        require(
            address(grant.ownerVault) != address(0),
            "GRANT_NOT_CREATED_YET"
        );
        require(msg.sender == grant.ownerVault.owner(), "NOT_VAULT_OWNER");
        (uint256 principalBalance, ) = grant.ownerVault.tokens(_token);
        require(_amount <= principalBalance, "NOT_ENOUGH_IN_OWNER_VAULT");

        grant.ownerVault.transferPrincipal(
            _token,
            _amount,
            address(grant.beneficiaryVault)
        );
        grant.beneficiaryVault.setPrincipalBalance(
            _token,
            grant.beneficiaryVault.getPrincipal(_token) + _amount
        );
        grant.tokens[_token].disbursed += _amount;

        emit StakedFundsDisbursed(_id, _token, _amount);
    }

    /*
     * HELPER
     */
    function getGrantTokenInfo(bytes32 _id, address _token)
        public
        view
        returns (uint256, uint256)
    {
        return (
            grants[_id].tokens[_token].allocated,
            grants[_id].tokens[_token].disbursed
        );
    }

    function getGrantId(address _owner, address _beneficiary)
        public
        view
        returns (bytes32)
    {
        ImpactVaultManager vaultMgr = getImpactVaultManager();
        ImpactVault ownerVault = vaultMgr.getOwnerVault(_owner, _beneficiary);
        ImpactVault beneficiaryVault = vaultMgr.getBeneficiaryVault(
            _beneficiary
        );
        return _getGrantId(address(ownerVault), address(beneficiaryVault));
    }

    function _getGrantId(address _ownerVault, address _beneficiaryVault)
        internal
        pure
        returns (bytes32)
    {
        return keccak256(abi.encodePacked(_ownerVault, _beneficiaryVault));
    }

    function getImpactVaultManager() public view returns (ImpactVaultManager) {
        return
            ImpactVaultManager(
                c_spiralsRegistry.getAddressForStringOrDie(
                    "spirals.ImpactVaultManager"
                )
            );
    }

    function getStakedCeloManager() internal view returns (IManager) {
        return
            IManager(
                c_spiralsRegistry.getAddressForStringOrDie("stCELO.Manager")
            );
    }

    function getCeloRegistry() internal view returns (IRegistry) {
        return
            IRegistry(
                c_spiralsRegistry.getAddressForStringOrDie(
                    "celo.SpiralsRegistry"
                )
            );
    }

    function getGoldToken() internal view returns (IERC20) {
        return IERC20(getCeloRegistry().getAddressForStringOrDie("GoldToken"));
    }

    function getStableToken() internal view returns (IERC20) {
        return
            IERC20(getCeloRegistry().getAddressForStringOrDie("StableToken"));
    }

    function pause() external onlyOwner {
        _pause();
    }

    function unpause() external onlyOwner {
        _unpause();
    }
}
        

Contract ABI

[{"type":"constructor","stateMutability":"nonpayable","inputs":[]},{"type":"event","name":"DependenciesUpdated","inputs":[{"type":"address","name":"spiralsRegistry","internalType":"address","indexed":false}],"anonymous":false},{"type":"event","name":"Initialized","inputs":[{"type":"uint8","name":"version","internalType":"uint8","indexed":false}],"anonymous":false},{"type":"event","name":"OwnershipTransferred","inputs":[{"type":"address","name":"previousOwner","internalType":"address","indexed":true},{"type":"address","name":"newOwner","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"Paused","inputs":[{"type":"address","name":"account","internalType":"address","indexed":false}],"anonymous":false},{"type":"event","name":"StakedFundsDisbursed","inputs":[{"type":"bytes32","name":"id","internalType":"bytes32","indexed":true},{"type":"address","name":"token","internalType":"address","indexed":true},{"type":"uint256","name":"amount","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"StakedGrantCreated","inputs":[{"type":"bytes32","name":"id","internalType":"bytes32","indexed":true},{"type":"address","name":"ownerVault","internalType":"address","indexed":true},{"type":"address","name":"beneficiaryVault","internalType":"address","indexed":true},{"type":"uint96","name":"_externalGrantId","internalType":"uint96","indexed":false}],"anonymous":false},{"type":"event","name":"StakedGrantFunded","inputs":[{"type":"bytes32","name":"id","internalType":"bytes32","indexed":true},{"type":"address","name":"token","internalType":"address","indexed":true},{"type":"uint256","name":"amount","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"Unpaused","inputs":[{"type":"address","name":"account","internalType":"address","indexed":false}],"anonymous":false},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract SpiralsRegistry"}],"name":"c_spiralsRegistry","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bytes32","name":"id","internalType":"bytes32"}],"name":"createGrant","inputs":[{"type":"address","name":"_beneficiary","internalType":"address"},{"type":"uint96","name":"_externalGrantId","internalType":"uint96"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"disburseFunds","inputs":[{"type":"bytes32","name":"_id","internalType":"bytes32"},{"type":"address","name":"_token","internalType":"address"},{"type":"uint256","name":"_amount","internalType":"uint256"}]},{"type":"function","stateMutability":"payable","outputs":[],"name":"fundGrant","inputs":[{"type":"bytes32","name":"_id","internalType":"bytes32"},{"type":"address","name":"_token","internalType":"address"},{"type":"uint256","name":"_amount","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"getGrantId","inputs":[{"type":"address","name":"_owner","internalType":"address"},{"type":"address","name":"_beneficiary","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"},{"type":"uint256","name":"","internalType":"uint256"}],"name":"getGrantTokenInfo","inputs":[{"type":"bytes32","name":"_id","internalType":"bytes32"},{"type":"address","name":"_token","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract ImpactVaultManager"}],"name":"getImpactVaultManager","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"initialize","inputs":[{"type":"address","name":"_registryAddress","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"owner","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"pause","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"paused","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"renounceOwnership","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setDependencies","inputs":[{"type":"address","name":"_registryAddress","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"transferOwnership","inputs":[{"type":"address","name":"newOwner","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"unpause","inputs":[]}]
              

Contract Creation Code

Verify & Publish
0x608060405234801561001057600080fd5b50611540806100206000396000f3fe6080604052600436106100e85760003560e01c80638389cb181161008a578063cd3244a911610059578063cd3244a91461024f578063efd7e26b14610262578063f2fde38b146102c6578063ffa5215e146102e657600080fd5b80638389cb18146101dc5780638456cb59146101fc5780638da5cb5b14610211578063c4d66de81461022f57600080fd5b80635e132e2b116100c65780635e132e2b1461015a57806368adc99c1461017a57806370aecfcd146101a7578063715018a6146101c757600080fd5b80633f4ba83a146100ed57806347f9eb88146101045780635c975abb14610137575b600080fd5b3480156100f957600080fd5b50610102610306565b005b34801561011057600080fd5b5061012461011f366004611324565b610318565b6040519081526020015b60405180910390f35b34801561014357600080fd5b5060655460ff16604051901515815260200161012e565b34801561016657600080fd5b5061010261017536600461135d565b610421565b34801561018657600080fd5b5061018f6107d8565b6040516001600160a01b03909116815260200161012e565b3480156101b357600080fd5b5060c95461018f906001600160a01b031681565b3480156101d357600080fd5b50610102610878565b3480156101e857600080fd5b506101026101f7366004611395565b61088a565b34801561020857600080fd5b506101026108ee565b34801561021d57600080fd5b506033546001600160a01b031661018f565b34801561023b57600080fd5b5061010261024a366004611395565b6108fe565b61010261025d36600461135d565b610a29565b34801561026e57600080fd5b506102b161027d3660046113b9565b600091825260ca602090815260408084206001600160a01b0393909316845260029092019052902080546001909101549091565b6040805192835260208301919091520161012e565b3480156102d257600080fd5b506101026102e1366004611395565b610be5565b3480156102f257600080fd5b506101246103013660046113de565b610c5e565b61030e610fdd565b610316611037565b565b6000806103236107d8565b604051635fc97dd960e11b81526001600160a01b038681166004830152858116602483015291925060009183169063bf92fbb290604401602060405180830381865afa158015610377573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061039b919061141d565b604051637d14fa2d60e01b81526001600160a01b038681166004830152919250600091841690637d14fa2d90602401602060405180830381865afa1580156103e7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061040b919061141d565b90506104178282611089565b9695505050505050565b6104296110d3565b600083815260ca6020526040902080546001600160a01b031661048b5760405162461bcd60e51b815260206004820152601560248201527411d490539517d393d517d0d4915055115117d65155605a1b60448201526064015b60405180910390fd5b805460408051638da5cb5b60e01b815290516001600160a01b0390921691638da5cb5b916004808201926020929091908290030181865afa1580156104d4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104f8919061141d565b6001600160a01b0316336001600160a01b03161461054a5760405162461bcd60e51b815260206004820152600f60248201526e2727aa2fab20aaa62a2fa7aba722a960891b6044820152606401610482565b805460405163e486033960e01b81526001600160a01b038581166004830152600092169063e4860339906024016040805180830381865afa158015610593573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105b7919061143a565b5090508083111561060a5760405162461bcd60e51b815260206004820152601960248201527f4e4f545f454e4f5547485f494e5f4f574e45525f5641554c54000000000000006044820152606401610482565b815460018301546040516313622a8f60e11b81526001600160a01b0387811660048301526024820187905291821660448201529116906326c4551e90606401600060405180830381600087803b15801561066357600080fd5b505af1158015610677573d6000803e3d6000fd5b505050506001820154604051637abdd2d160e01b81526001600160a01b03868116600483015290911690630a53665d90869086908490637abdd2d190602401602060405180830381865afa1580156106d3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106f7919061145e565b6107019190611477565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b15801561074757600080fd5b505af115801561075b573d6000803e3d6000fd5b505050506001600160a01b03841660009081526002830160205260408120600101805485929061078c908490611477565b90915550506040518381526001600160a01b0385169086907f87901352285fd61756221feccf8d641ba0141f60a6578e8847dafd24a3726a3d9060200160405180910390a35050505050565b60c95460405163224cb2fd60e21b815260206004820152601a60248201527f73706972616c732e496d706163745661756c744d616e6167657200000000000060448201526000916001600160a01b031690638932cbf490606401602060405180830381865afa15801561084f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610873919061141d565b905090565b610880610fdd565b6103166000611119565b610892610fdd565b61089a6110d3565b60c980546001600160a01b0319166001600160a01b0383169081179091556040519081527f8ef56a434a163c7aca485bff516c656927843bad119d8524144197adc507c78a9060200160405180910390a150565b6108f6610fdd565b61031661116b565b600054610100900460ff161580801561091e5750600054600160ff909116105b806109385750303b158015610938575060005460ff166001145b61099b5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610482565b6000805460ff1916600117905580156109be576000805461ff0019166101001790555b6109c66111a8565b6109ce6111d7565b6109d6611206565b6109df8261088a565b8015610a25576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b610a316110d3565b600083815260ca6020526040902080546001600160a01b0316610a8e5760405162461bcd60e51b815260206004820152601560248201527411d490539517d393d517d0d4915055115117d65155605a1b6044820152606401610482565b80546040516323b872dd60e01b81523360048201526001600160a01b03918216602482015260448101849052908416906323b872dd906064016020604051808303816000875af1158015610ae6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b0a919061149d565b5080546040516356e4bb9760e11b81526001600160a01b038581166004830152602482018590529091169063adc9772e90604401600060405180830381600087803b158015610b5857600080fd5b505af1158015610b6c573d6000803e3d6000fd5b505050506001600160a01b038316600090815260028201602052604081208054849290610b9a908490611477565b90915550506040518281526001600160a01b0384169085907fb0a405a464ca269b946db995bae62c9cbed6db2c555c6de72c015b19591dab0e9060200160405180910390a350505050565b610bed610fdd565b6001600160a01b038116610c525760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610482565b610c5b81611119565b50565b6000610c686110d3565b6000610c726107d8565b60405163be73d86760e01b815233600482018190526001600160a01b038781166024840152929350916000919084169063be73d86790604401602060405180830381865afa158015610cc8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cec919061145e565b604051637780ad5560e11b8152600481018290529091506000906001600160a01b0385169063ef015aaa90602401602060405180830381865afa158015610d37573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d5b919061141d565b90506001600160a01b038116610de257604051630f78946560e21b81526001600160a01b0384811660048301528881166024830152851690633de25194906044016020604051808303816000875af1158015610dbb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ddf919061141d565b90505b60405163b8689ded60e01b81526001600160a01b0388811660048301526000919086169063b8689ded90602401602060405180830381865afa158015610e2c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e50919061145e565b604051637780ad5560e11b8152600481018290529091506000906001600160a01b0387169063ef015aaa90602401602060405180830381865afa158015610e9b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ebf919061141d565b90506001600160a01b038116610f3e57604051634c18e19b60e01b81526001600160a01b038a81166004830152871690634c18e19b906024016020604051808303816000875af1158015610f17573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f3b919061141d565b90505b610f488382611089565b600081815260ca602090815260409182902080546001600160a01b038881166001600160a01b03199283168117845560018401805492891692909316821790925593516bffffffffffffffffffffffff8e168152949b50909390918b917f53fc77da9fde034140e3d7c01e91832e64304833618adb86e60ae2f43b1bb3e0910160405180910390a45050505050505092915050565b6033546001600160a01b031633146103165760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610482565b61103f611235565b6065805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b6040516bffffffffffffffffffffffff19606084811b8216602084015283901b16603482015260009060480160405160208183030381529060405280519060200120905092915050565b60655460ff16156103165760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610482565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6111736110d3565b6065805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25861106c3390565b600054610100900460ff166111cf5760405162461bcd60e51b8152600401610482906114bf565b61031661127e565b600054610100900460ff166111fe5760405162461bcd60e51b8152600401610482906114bf565b6103166112ae565b600054610100900460ff1661122d5760405162461bcd60e51b8152600401610482906114bf565b6103166112e1565b60655460ff166103165760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b6044820152606401610482565b600054610100900460ff166112a55760405162461bcd60e51b8152600401610482906114bf565b61031633611119565b600054610100900460ff166112d55760405162461bcd60e51b8152600401610482906114bf565b6065805460ff19169055565b600054610100900460ff166113085760405162461bcd60e51b8152600401610482906114bf565b6001609755565b6001600160a01b0381168114610c5b57600080fd5b6000806040838503121561133757600080fd5b82356113428161130f565b915060208301356113528161130f565b809150509250929050565b60008060006060848603121561137257600080fd5b8335925060208401356113848161130f565b929592945050506040919091013590565b6000602082840312156113a757600080fd5b81356113b28161130f565b9392505050565b600080604083850312156113cc57600080fd5b8235915060208301356113528161130f565b600080604083850312156113f157600080fd5b82356113fc8161130f565b915060208301356bffffffffffffffffffffffff8116811461135257600080fd5b60006020828403121561142f57600080fd5b81516113b28161130f565b6000806040838503121561144d57600080fd5b505080516020909101519092909150565b60006020828403121561147057600080fd5b5051919050565b6000821982111561149857634e487b7160e01b600052601160045260246000fd5b500190565b6000602082840312156114af57600080fd5b815180151581146113b257600080fd5b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b60608201526080019056fea2646970667358221220fa7a39d12e6efefb16fdcd28a12baeab367bcbf89b1e890087e2f8665b3305be64736f6c634300080b0033

Deployed ByteCode

0x6080604052600436106100e85760003560e01c80638389cb181161008a578063cd3244a911610059578063cd3244a91461024f578063efd7e26b14610262578063f2fde38b146102c6578063ffa5215e146102e657600080fd5b80638389cb18146101dc5780638456cb59146101fc5780638da5cb5b14610211578063c4d66de81461022f57600080fd5b80635e132e2b116100c65780635e132e2b1461015a57806368adc99c1461017a57806370aecfcd146101a7578063715018a6146101c757600080fd5b80633f4ba83a146100ed57806347f9eb88146101045780635c975abb14610137575b600080fd5b3480156100f957600080fd5b50610102610306565b005b34801561011057600080fd5b5061012461011f366004611324565b610318565b6040519081526020015b60405180910390f35b34801561014357600080fd5b5060655460ff16604051901515815260200161012e565b34801561016657600080fd5b5061010261017536600461135d565b610421565b34801561018657600080fd5b5061018f6107d8565b6040516001600160a01b03909116815260200161012e565b3480156101b357600080fd5b5060c95461018f906001600160a01b031681565b3480156101d357600080fd5b50610102610878565b3480156101e857600080fd5b506101026101f7366004611395565b61088a565b34801561020857600080fd5b506101026108ee565b34801561021d57600080fd5b506033546001600160a01b031661018f565b34801561023b57600080fd5b5061010261024a366004611395565b6108fe565b61010261025d36600461135d565b610a29565b34801561026e57600080fd5b506102b161027d3660046113b9565b600091825260ca602090815260408084206001600160a01b0393909316845260029092019052902080546001909101549091565b6040805192835260208301919091520161012e565b3480156102d257600080fd5b506101026102e1366004611395565b610be5565b3480156102f257600080fd5b506101246103013660046113de565b610c5e565b61030e610fdd565b610316611037565b565b6000806103236107d8565b604051635fc97dd960e11b81526001600160a01b038681166004830152858116602483015291925060009183169063bf92fbb290604401602060405180830381865afa158015610377573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061039b919061141d565b604051637d14fa2d60e01b81526001600160a01b038681166004830152919250600091841690637d14fa2d90602401602060405180830381865afa1580156103e7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061040b919061141d565b90506104178282611089565b9695505050505050565b6104296110d3565b600083815260ca6020526040902080546001600160a01b031661048b5760405162461bcd60e51b815260206004820152601560248201527411d490539517d393d517d0d4915055115117d65155605a1b60448201526064015b60405180910390fd5b805460408051638da5cb5b60e01b815290516001600160a01b0390921691638da5cb5b916004808201926020929091908290030181865afa1580156104d4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104f8919061141d565b6001600160a01b0316336001600160a01b03161461054a5760405162461bcd60e51b815260206004820152600f60248201526e2727aa2fab20aaa62a2fa7aba722a960891b6044820152606401610482565b805460405163e486033960e01b81526001600160a01b038581166004830152600092169063e4860339906024016040805180830381865afa158015610593573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105b7919061143a565b5090508083111561060a5760405162461bcd60e51b815260206004820152601960248201527f4e4f545f454e4f5547485f494e5f4f574e45525f5641554c54000000000000006044820152606401610482565b815460018301546040516313622a8f60e11b81526001600160a01b0387811660048301526024820187905291821660448201529116906326c4551e90606401600060405180830381600087803b15801561066357600080fd5b505af1158015610677573d6000803e3d6000fd5b505050506001820154604051637abdd2d160e01b81526001600160a01b03868116600483015290911690630a53665d90869086908490637abdd2d190602401602060405180830381865afa1580156106d3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106f7919061145e565b6107019190611477565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b15801561074757600080fd5b505af115801561075b573d6000803e3d6000fd5b505050506001600160a01b03841660009081526002830160205260408120600101805485929061078c908490611477565b90915550506040518381526001600160a01b0385169086907f87901352285fd61756221feccf8d641ba0141f60a6578e8847dafd24a3726a3d9060200160405180910390a35050505050565b60c95460405163224cb2fd60e21b815260206004820152601a60248201527f73706972616c732e496d706163745661756c744d616e6167657200000000000060448201526000916001600160a01b031690638932cbf490606401602060405180830381865afa15801561084f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610873919061141d565b905090565b610880610fdd565b6103166000611119565b610892610fdd565b61089a6110d3565b60c980546001600160a01b0319166001600160a01b0383169081179091556040519081527f8ef56a434a163c7aca485bff516c656927843bad119d8524144197adc507c78a9060200160405180910390a150565b6108f6610fdd565b61031661116b565b600054610100900460ff161580801561091e5750600054600160ff909116105b806109385750303b158015610938575060005460ff166001145b61099b5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610482565b6000805460ff1916600117905580156109be576000805461ff0019166101001790555b6109c66111a8565b6109ce6111d7565b6109d6611206565b6109df8261088a565b8015610a25576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b610a316110d3565b600083815260ca6020526040902080546001600160a01b0316610a8e5760405162461bcd60e51b815260206004820152601560248201527411d490539517d393d517d0d4915055115117d65155605a1b6044820152606401610482565b80546040516323b872dd60e01b81523360048201526001600160a01b03918216602482015260448101849052908416906323b872dd906064016020604051808303816000875af1158015610ae6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b0a919061149d565b5080546040516356e4bb9760e11b81526001600160a01b038581166004830152602482018590529091169063adc9772e90604401600060405180830381600087803b158015610b5857600080fd5b505af1158015610b6c573d6000803e3d6000fd5b505050506001600160a01b038316600090815260028201602052604081208054849290610b9a908490611477565b90915550506040518281526001600160a01b0384169085907fb0a405a464ca269b946db995bae62c9cbed6db2c555c6de72c015b19591dab0e9060200160405180910390a350505050565b610bed610fdd565b6001600160a01b038116610c525760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610482565b610c5b81611119565b50565b6000610c686110d3565b6000610c726107d8565b60405163be73d86760e01b815233600482018190526001600160a01b038781166024840152929350916000919084169063be73d86790604401602060405180830381865afa158015610cc8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cec919061145e565b604051637780ad5560e11b8152600481018290529091506000906001600160a01b0385169063ef015aaa90602401602060405180830381865afa158015610d37573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d5b919061141d565b90506001600160a01b038116610de257604051630f78946560e21b81526001600160a01b0384811660048301528881166024830152851690633de25194906044016020604051808303816000875af1158015610dbb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ddf919061141d565b90505b60405163b8689ded60e01b81526001600160a01b0388811660048301526000919086169063b8689ded90602401602060405180830381865afa158015610e2c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e50919061145e565b604051637780ad5560e11b8152600481018290529091506000906001600160a01b0387169063ef015aaa90602401602060405180830381865afa158015610e9b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ebf919061141d565b90506001600160a01b038116610f3e57604051634c18e19b60e01b81526001600160a01b038a81166004830152871690634c18e19b906024016020604051808303816000875af1158015610f17573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f3b919061141d565b90505b610f488382611089565b600081815260ca602090815260409182902080546001600160a01b038881166001600160a01b03199283168117845560018401805492891692909316821790925593516bffffffffffffffffffffffff8e168152949b50909390918b917f53fc77da9fde034140e3d7c01e91832e64304833618adb86e60ae2f43b1bb3e0910160405180910390a45050505050505092915050565b6033546001600160a01b031633146103165760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610482565b61103f611235565b6065805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b6040516bffffffffffffffffffffffff19606084811b8216602084015283901b16603482015260009060480160405160208183030381529060405280519060200120905092915050565b60655460ff16156103165760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610482565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6111736110d3565b6065805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25861106c3390565b600054610100900460ff166111cf5760405162461bcd60e51b8152600401610482906114bf565b61031661127e565b600054610100900460ff166111fe5760405162461bcd60e51b8152600401610482906114bf565b6103166112ae565b600054610100900460ff1661122d5760405162461bcd60e51b8152600401610482906114bf565b6103166112e1565b60655460ff166103165760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b6044820152606401610482565b600054610100900460ff166112a55760405162461bcd60e51b8152600401610482906114bf565b61031633611119565b600054610100900460ff166112d55760405162461bcd60e51b8152600401610482906114bf565b6065805460ff19169055565b600054610100900460ff166113085760405162461bcd60e51b8152600401610482906114bf565b6001609755565b6001600160a01b0381168114610c5b57600080fd5b6000806040838503121561133757600080fd5b82356113428161130f565b915060208301356113528161130f565b809150509250929050565b60008060006060848603121561137257600080fd5b8335925060208401356113848161130f565b929592945050506040919091013590565b6000602082840312156113a757600080fd5b81356113b28161130f565b9392505050565b600080604083850312156113cc57600080fd5b8235915060208301356113528161130f565b600080604083850312156113f157600080fd5b82356113fc8161130f565b915060208301356bffffffffffffffffffffffff8116811461135257600080fd5b60006020828403121561142f57600080fd5b81516113b28161130f565b6000806040838503121561144d57600080fd5b505080516020909101519092909150565b60006020828403121561147057600080fd5b5051919050565b6000821982111561149857634e487b7160e01b600052601160045260246000fd5b500190565b6000602082840312156114af57600080fd5b815180151581146113b257600080fd5b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b60608201526080019056fea2646970667358221220fa7a39d12e6efefb16fdcd28a12baeab367bcbf89b1e890087e2f8665b3305be64736f6c634300080b0033

External libraries