ETH Price: $3,392.88 (+1.74%)

Token

PieDAO Balanced Crypto Pie (BCP)
 

Overview

Max Total Supply

219,569.255579305850530875 BCP

Holders

470 (0.00%)

Market

Onchain Market Cap

$0.00

Circulating Supply Market Cap

-

Other Info

Token Contract (WITH 18 Decimals)

Balance
77.181522467423016309 BCP

Value
$0.00
0x03e81230EDB43a393d33B4e6724F31b955327f0C
Loading...
Loading
Loading...
Loading
Loading...
Loading

OVERVIEW

BCP gives equal Bitcoin, Ether, and DeFi exposure in one easy to access ERC20 token, automatically rebalanced.

# Exchange Pair Price  24H Volume % Volume

Similar Match Source Code
This contract matches the deployed Bytecode of the Source Code for Contract 0x03271124...B9f7C33fd
The constructor portion of the code might be different and could alter the actual behaviour of the contract

Contract Name:
PProxyPausable

Compiler Version
v0.6.4+commit.1dca32f3

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, None license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2020-04-02
*/

/**
 *Submitted for verification at Etherscan.io on 2020-04-02
*/

// Sources flattened with buidler v1.2.0 https://buidler.dev

// File @pie-dao/proxy/contracts/[email protected]

pragma solidity ^0.6.2;

contract PProxyStorage {

    function readString(bytes32 _key) public view returns(string memory) {
        return bytes32ToString(storageRead(_key));
    }

    function setString(bytes32 _key, string memory _value) internal {
        storageSet(_key, stringToBytes32(_value));
    }

    function readBool(bytes32 _key) public view returns(bool) {
        return storageRead(_key) == bytes32(uint256(1));
    }

    function setBool(bytes32 _key, bool _value) internal {
        if(_value) {
            storageSet(_key, bytes32(uint256(1)));
        } else {
            storageSet(_key, bytes32(uint256(0)));
        }
    }

    function readAddress(bytes32 _key) public view returns(address) {
        return bytes32ToAddress(storageRead(_key));
    }

    function setAddress(bytes32 _key, address _value) internal {
        storageSet(_key, addressToBytes32(_value));
    }

    function storageRead(bytes32 _key) public view returns(bytes32) {
        bytes32 value;
        //solium-disable-next-line security/no-inline-assembly
        assembly {
            value := sload(_key)
        }
        return value;
    }

    function storageSet(bytes32 _key, bytes32 _value) internal {
        // targetAddress = _address;  // No!
        bytes32 implAddressStorageKey = _key;
        //solium-disable-next-line security/no-inline-assembly
        assembly {
            sstore(implAddressStorageKey, _value)
        }
    }

    function bytes32ToAddress(bytes32 _value) public pure returns(address) {
        return address(uint160(uint256(_value)));
    }

    function addressToBytes32(address _value) public pure returns(bytes32) {
        return bytes32(uint256(_value));
    }

    function stringToBytes32(string memory _value) public pure returns (bytes32 result) {
        bytes memory tempEmptyStringTest = bytes(_value);
        if (tempEmptyStringTest.length == 0) {
            return 0x0;
        }

        assembly {
            result := mload(add(_value, 32))
        }
    }

    function bytes32ToString(bytes32 _value) public pure returns (string memory) {
        bytes memory bytesString = new bytes(32);
        uint charCount = 0;
        for (uint256 j = 0; j < 32; j++) {
            byte char = byte(bytes32(uint(_value) * 2 ** (8 * j)));
            if (char != 0) {
                bytesString[charCount] = char;
                charCount++;
            }
        }
        bytes memory bytesStringTrimmed = new bytes(charCount);
        for (uint256 j = 0; j < charCount; j++) {
            bytesStringTrimmed[j] = bytesString[j];
        }
        return string(bytesStringTrimmed);
    }
}


// File @pie-dao/proxy/contracts/[email protected]

pragma solidity ^0.6.2;


contract PProxy is PProxyStorage {

    bytes32 constant IMPLEMENTATION_SLOT = keccak256(abi.encodePacked("IMPLEMENTATION_SLOT"));
    bytes32 constant OWNER_SLOT = keccak256(abi.encodePacked("OWNER_SLOT"));

    modifier onlyProxyOwner() {
        require(msg.sender == readAddress(OWNER_SLOT), "PProxy.onlyProxyOwner: msg sender not owner");
        _;
    }

    constructor () public {
        setAddress(OWNER_SLOT, msg.sender);
    }

    function getProxyOwner() public view returns (address) {
       return readAddress(OWNER_SLOT);
    }

    function setProxyOwner(address _newOwner) onlyProxyOwner public {
        setAddress(OWNER_SLOT, _newOwner);
    }

    function getImplementation() public view returns (address) {
        return readAddress(IMPLEMENTATION_SLOT);
    }

    function setImplementation(address _newImplementation) onlyProxyOwner public {
        setAddress(IMPLEMENTATION_SLOT, _newImplementation);
    }


    fallback () external payable {
       return internalFallback();
    }

    function internalFallback() internal virtual {
        address contractAddr = readAddress(IMPLEMENTATION_SLOT);
        assembly {
            let ptr := mload(0x40)
            calldatacopy(ptr, 0, calldatasize())
            let result := delegatecall(gas(), contractAddr, ptr, calldatasize(), 0, 0)
            let size := returndatasize()
            returndatacopy(ptr, 0, size)

            switch result
            case 0 { revert(ptr, size) }
            default { return(ptr, size) }
        }
    }

}


// File @pie-dao/proxy/contracts/[email protected]

pragma solidity ^0.6.2;


contract PProxyPausable is PProxy {

    bytes32 constant PAUSED_SLOT = keccak256(abi.encodePacked("PAUSED_SLOT"));
    bytes32 constant PAUZER_SLOT = keccak256(abi.encodePacked("PAUZER_SLOT"));

    constructor() PProxy() public {
        setAddress(PAUZER_SLOT, msg.sender);
    }

    modifier onlyPauzer() {
        require(msg.sender == readAddress(PAUZER_SLOT), "PProxyPausable.onlyPauzer: msg sender not pauzer");
        _;
    }

    modifier notPaused() {
        require(!readBool(PAUSED_SLOT), "PProxyPausable.notPaused: contract is paused");
        _;
    }

    function getPauzer() public view returns (address) {
        return readAddress(PAUZER_SLOT);
    }

    function setPauzer(address _newPauzer) public onlyProxyOwner{
        setAddress(PAUZER_SLOT, _newPauzer);
    }

    function renouncePauzer() public onlyPauzer {
        setAddress(PAUZER_SLOT, address(0));
    }

    function getPaused() public view returns (bool) {
        return readBool(PAUSED_SLOT);
    }

    function setPaused(bool _value) public onlyPauzer {
        setBool(PAUSED_SLOT, _value);
    }

    function internalFallback() internal virtual override notPaused {
        super.internalFallback();
    }

}


// File contracts/interfaces/IBFactory.sol

pragma solidity ^0.6.4;

interface IBFactory {
    function newBPool() external returns (address);
}


// File contracts/interfaces/IBPool.sol

// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// This program is disstributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

pragma solidity 0.6.4;

interface IBPool {
    function isBound(address token) external view returns(bool);
    function getBalance(address token) external view returns (uint);
    function rebind(address token, uint balance, uint denorm) external;
    function setSwapFee(uint swapFee) external;
    function setPublicSwap(bool _public) external;
    function bind(address token, uint balance, uint denorm) external;
    function unbind(address token) external;
    function getDenormalizedWeight(address token) external view returns (uint);
    function getTotalDenormalizedWeight() external view returns (uint);
    function getCurrentTokens() external view returns(address[] memory);
    function setController(address manager) external;
    function isPublicSwap() external view returns(bool);
    function getSwapFee() external view returns (uint256);
    function gulp(address token) external;

    function calcPoolOutGivenSingleIn(
        uint tokenBalanceIn,
        uint tokenWeightIn,
        uint poolSupply,
        uint totalWeight,
        uint tokenAmountIn,
        uint swapFee
    )
        external pure
        returns (uint poolAmountOut);

    function calcSingleInGivenPoolOut(
        uint tokenBalanceIn,
        uint tokenWeightIn,
        uint poolSupply,
        uint totalWeight,
        uint poolAmountOut,
        uint swapFee
    )
        external pure
        returns (uint tokenAmountIn);

    function calcSingleOutGivenPoolIn(
        uint tokenBalanceOut,
        uint tokenWeightOut,
        uint poolSupply,
        uint totalWeight,
        uint poolAmountIn,
        uint swapFee
    )
        external pure
        returns (uint tokenAmountOut);

    function calcPoolInGivenSingleOut(
        uint tokenBalanceOut,
        uint tokenWeightOut,
        uint poolSupply,
        uint totalWeight,
        uint tokenAmountOut,
        uint swapFee
    )
        external pure
        returns (uint poolAmountIn);
}


// File contracts/interfaces/IERC20.sol

pragma solidity ^0.6.4;

interface IERC20 {
    event Approval(address indexed _src, address indexed _dst, uint _amount);
    event Transfer(address indexed _src, address indexed _dst, uint _amount);

    function totalSupply() external view returns (uint);
    function balanceOf(address _whom) external view returns (uint);
    function allowance(address _src, address _dst) external view returns (uint);

    function approve(address _dst, uint _amount) external returns (bool);
    function transfer(address _dst, uint _amount) external returns (bool);
    function transferFrom(
        address _src, address _dst, uint _amount
    ) external returns (bool);
}


// File contracts/Ownable.sol

pragma solidity ^0.6.4;

// TODO move this generic contract to a seperate repo with all generic smart contracts

contract Ownable {

    bytes32 constant public oSlot = keccak256("Ownable.storage.location");

    event OwnerChanged(address indexed previousOwner, address indexed newOwner);

    // Ownable struct
    struct os {
        address owner;
    }

    modifier onlyOwner(){
        require(msg.sender == los().owner, "Ownable.onlyOwner: msg.sender not owner");
        _;
    }

    /**
        @notice Transfer ownership to a new address
        @param _newOwner Address of the new owner
    */
    function transferOwnership(address _newOwner) onlyOwner external {
        _setOwner(_newOwner);
    }

    /**
        @notice Internal method to set the owner
        @param _newOwner Address of the new owner
    */
    function _setOwner(address _newOwner) internal {
        emit OwnerChanged(los().owner, _newOwner);
        los().owner = _newOwner;
    }

    /**
        @notice Load ownable storage
        @return s Storage pointer to the Ownable storage struct
    */
    function los() internal pure returns (os storage s) {
        bytes32 loc = oSlot;
        assembly {
            s_slot := loc
        }
    }

}


// File contracts/interfaces/IPSmartPool.sol

pragma solidity ^0.6.4;

interface IPSmartPool is IERC20 {
    function joinPool(uint256 _amount) external;
    function exitPool(uint256 _amount) external;
    function getController() external view returns(address);
    function getTokens() external view returns(address[] memory);
    function calcTokensForAmount(uint256 _amount) external view  returns(address[] memory tokens, uint256[] memory amounts);
}


// File contracts/PCTokenStorage.sol

pragma solidity ^0.6.4;

contract PCTokenStorage {

    bytes32 constant public ptSlot = keccak256("PCToken.storage.location");
    struct pts {
        string name;
        string symbol;
        uint256 totalSupply;
        mapping(address => uint256) balance;
        mapping(address => mapping(address=>uint256)) allowance;
    }

    /**
        @notice Load pool token storage
        @return s Storage pointer to the pool token struct
    */
    function lpts() internal pure returns (pts storage s) {
        bytes32 loc = ptSlot;
        assembly {
            s_slot := loc
        }
    }

}


// File contracts/PCToken.sol

// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

pragma solidity ^0.6.4;



// Highly opinionated token implementation
// Based on the balancer Implementation


contract PCToken is IERC20, PCTokenStorage {

    event Approval(address indexed _src, address indexed _dst, uint _amount);
    event Transfer(address indexed _src, address indexed _dst, uint _amount);

    uint8 public constant decimals = 18;
    uint public constant BONE              = 10**18;
    uint public constant MAX_BOUND_TOKENS  = 8;
    uint public constant MIN_WEIGHT        = BONE;
    uint public constant MAX_WEIGHT        = BONE * 50;
    uint public constant MAX_TOTAL_WEIGHT  = BONE * 50;
    uint public constant MIN_BALANCE       = BONE / 10**6;
    uint public constant MAX_BALANCE       = BONE * 10**12;

    uint public constant MIN_POOL_SUPPLY   = BONE;

    function badd(uint a, uint b)
        internal pure
        returns (uint)
    {
        uint c = a + b;
        require(c >= a, "ERR_ADD_OVERFLOW");
        return c;
    }

    function bsub(uint a, uint b)
        internal pure
        returns (uint)
    {
        (uint c, bool flag) = bsubSign(a, b);
        require(!flag, "ERR_SUB_UNDERFLOW");
        return c;
    }

    function bsubSign(uint a, uint b)
        internal pure
        returns (uint, bool)
    {
        if (a >= b) {
            return (a - b, false);
        } else {
            return (b - a, true);
        }
    }

    function bmul(uint a, uint b)
        internal pure
        returns (uint)
    {
        uint c0 = a * b;
        require(a == 0 || c0 / a == b, "ERR_MUL_OVERFLOW");
        uint c1 = c0 + (BONE / 2);
        require(c1 >= c0, "ERR_MUL_OVERFLOW");
        uint c2 = c1 / BONE;
        return c2;
    }

    function bdiv(uint a, uint b)
        internal pure
        returns (uint)
    {
        require(b != 0, "ERR_DIV_ZERO");
        uint c0 = a * BONE;
        require(a == 0 || c0 / a == BONE, "ERR_DIV_INTERNAL"); // bmul overflow
        uint c1 = c0 + (b / 2);
        require(c1 >= c0, "ERR_DIV_INTERNAL"); //  badd require
        uint c2 = c1 / b;
        return c2;
    }

    function _mint(uint _amount) internal {
        pts storage s = lpts();
        s.balance[address(this)] = badd(s.balance[address(this)], _amount);
        s.totalSupply = badd(s.totalSupply, _amount);
        emit Transfer(address(0), address(this), _amount);
    }

    function _burn(uint _amount) internal {
        pts storage s = lpts();
        require(s.balance[address(this)] >= _amount, "ERR_INSUFFICIENT_BAL");
        s.balance[address(this)] = bsub(s.balance[address(this)], _amount);
        s.totalSupply = bsub(s.totalSupply, _amount);
        emit Transfer(address(this), address(0), _amount);
    }

    function _move(address _src, address _dst, uint _amount) internal {
        pts storage s = lpts();
        require(s.balance[_src] >= _amount, "ERR_INSUFFICIENT_BAL");
        s.balance[_src] = bsub(s.balance[_src], _amount);
        s.balance[_dst] = badd(s.balance[_dst], _amount);
        emit Transfer(_src, _dst, _amount);
    }

    function _push(address _to, uint _amount) internal {
        _move(address(this), _to, _amount);
    }

    function _pull(address _from, uint _amount) internal {
        _move(_from, address(this), _amount);
    }

    function allowance(address _src, address _dst) external view override returns (uint) {
        return lpts().allowance[_src][_dst];
    }

    function balanceOf(address _whom) external view override returns (uint) {
        return lpts().balance[_whom];
    }

    function totalSupply() public view override returns (uint) {
        return lpts().totalSupply;
    }

    function name() external view returns (string memory) {
        return lpts().name;
    }

    function symbol() external view returns (string memory) {
        return lpts().symbol;
    }

    function approve(address _dst, uint _amount) external override returns (bool) {
        lpts().allowance[msg.sender][_dst] = _amount;
        emit Approval(msg.sender, _dst, _amount);
        return true;
    }

    function increaseApproval(address _dst, uint _amount) external returns (bool) {
        pts storage s = lpts();
        s.allowance[msg.sender][_dst] = badd(s.allowance[msg.sender][_dst], _amount);
        emit Approval(msg.sender, _dst, s.allowance[msg.sender][_dst]);
        return true;
    }

    function decreaseApproval(address _dst, uint _amount) external returns (bool) {
        pts storage s = lpts();
        uint oldValue = s.allowance[msg.sender][_dst];
        if (_amount > oldValue) {
            s.allowance[msg.sender][_dst] = 0;
        } else {
            s.allowance[msg.sender][_dst] = bsub(oldValue, _amount);
        }
        emit Approval(msg.sender, _dst, s.allowance[msg.sender][_dst]);
        return true;
    }

    function transfer(address _dst, uint _amount) external override returns (bool) {
        _move(msg.sender, _dst, _amount);
        return true;
    }

    function transferFrom(address _src, address _dst, uint _amount) external override returns (bool) {
        pts storage s = lpts();
        require(msg.sender == _src || _amount <= s.allowance[_src][msg.sender], "ERR_PCTOKEN_BAD_CALLER");
        _move(_src, _dst, _amount);
        if (msg.sender != _src && s.allowance[_src][msg.sender] != uint256(-1)) {
            s.allowance[_src][msg.sender] = bsub(s.allowance[_src][msg.sender], _amount);
            emit Approval(msg.sender, _dst, s.allowance[_src][msg.sender]);
        }
        return true;
    }
}


// File contracts/ReentryProtection.sol

pragma solidity ^0.6.4;

// TODO move this generic contract to a seperate repo with all generic smart contracts

contract ReentryProtection {

    bytes32 constant public rpSlot = keccak256("ReentryProtection.storage.location");

    // reentry protection storage
    struct rps {
        uint256 lockCounter;
    }

    modifier noReentry {
        // Use counter to only write to storage once
        lrps().lockCounter ++;
        uint256 lockValue = lrps().lockCounter;
        _;
        require(lockValue == lrps().lockCounter, "ReentryProtection.noReentry: reentry detected");
    }

    /**
        @notice Load reentry protection storage
        @return s Pointer to the reentry protection storage struct
    */
    function lrps() internal pure returns (rps storage s) {
        bytes32 loc = rpSlot;
        assembly {
            s_slot := loc
        }
    }

}


// File contracts/smart-pools/PBasicSmartPool.sol

pragma solidity ^0.6.4;





contract PBasicSmartPool is IPSmartPool, PCToken, ReentryProtection {
    
    // P Basic Smart Struct
    bytes32 constant public pbsSlot = keccak256("PBasicSmartPool.storage.location");
    struct pbs {
        IBPool bPool;
        address controller;
        address publicSwapSetter;
        address tokenBinder;
    }
    
    modifier ready() {
        require(address(lpbs().bPool) != address(0), "PBasicSmartPool.ready: not ready");
        _;
    }   

     event LOG_JOIN(
        address indexed caller,
        address indexed tokenIn,
        uint256 tokenAmountIn
    );

    event LOG_EXIT(
        address indexed caller,
        address indexed tokenOut,
        uint256 tokenAmountOut
    );

    event TokensApproved();
    event ControllerChanged(address indexed previousController, address indexed newController);
    event PublicSwapSetterChanged(address indexed previousSetter, address indexed newSetter);
    event TokenBinderChanged(address indexed previousTokenBinder, address indexed newTokenBinder);
    event PublicSwapSet(address indexed setter, bool indexed value);
    event SwapFeeSet(address indexed setter, uint256 newFee);
    event PoolJoined(address indexed from, uint256 amount);
    event PoolExited(address indexed from, uint256 amount);

    modifier onlyController() {
        require(msg.sender == lpbs().controller, "PBasicSmartPool.onlyController: not controller");
        _;
    }

    modifier onlyPublicSwapSetter() {
        require(msg.sender == lpbs().publicSwapSetter, "PBasicSmartPool.onlyPublicSwapSetter: not public swap setter");
        _;
    }

    modifier onlyTokenBinder() {
        require(msg.sender == lpbs().tokenBinder, "PBasicSmartPool.onlyTokenBinder: not token binder");
        _;
    }

    /**
        @notice Initialises the contract
        @param _bPool Address of the underlying balancer pool
        @param _name Name for the smart pool token
        @param _symbol Symbol for the smart pool token
        @param _initialSupply Initial token supply to mint
    */
    function init(address _bPool, string calldata _name, string calldata _symbol, uint256 _initialSupply) external {
        pbs storage s = lpbs();
        require(address(s.bPool) == address(0), "PBasicSmartPool.init: already initialised");
        s.bPool = IBPool(_bPool);
        s.controller = msg.sender;
        s.publicSwapSetter = msg.sender;
        s.tokenBinder = msg.sender;
        lpts().name = _name;
        lpts().symbol = _symbol;
        _mintPoolShare(_initialSupply);
        _pushPoolShare(msg.sender, _initialSupply);
    }

    /**
        @notice Sets approval to all tokens to the underlying balancer pool
        @dev It uses this function to save on gas in joinPool
    */
    function approveTokens() public {
        IBPool bPool = lpbs().bPool;
        address[] memory tokens = bPool.getCurrentTokens();
        for(uint256 i = 0; i < tokens.length; i ++) {
            IERC20(tokens[i]).approve(address(bPool), uint256(-1));
        }
        emit TokensApproved();
    }

    /**
        @notice Sets the controller address. Can only be set by the current controller
        @param _controller Address of the new controller
    */
    function setController(address _controller) onlyController noReentry external {
        emit ControllerChanged(lpbs().controller, _controller);
        lpbs().controller = _controller;
    }

    /**
        @notice Sets public swap setter address. Can only be set by the controller
        @param _newPublicSwapSetter Address of the new public swap setter
    */
    function setPublicSwapSetter(address _newPublicSwapSetter) onlyController external {
        emit PublicSwapSetterChanged(lpbs().publicSwapSetter, _newPublicSwapSetter);
        lpbs().publicSwapSetter = _newPublicSwapSetter;
    }

    /**
        @notice Sets the token binder address. Can only be set by the controller
        @param _newTokenBinder Address of the new token binder
    */
    function setTokenBinder(address _newTokenBinder) onlyController external {
        emit TokenBinderChanged(lpbs().tokenBinder, _newTokenBinder);
        lpbs().tokenBinder = _newTokenBinder;
    }

    /**
        @notice Enables or disables public swapping on the underlying balancer pool. Can only be set by the controller
        @param _public Public or not
    */
    function setPublicSwap(bool _public) onlyPublicSwapSetter external {
        emit PublicSwapSet(msg.sender, _public);
        lpbs().bPool.setPublicSwap(_public);
    }

    /**
        @notice Set the swap fee on the underlying balancer pool. Can only be called by the controller
        @param _swapFee The new swap fee
    */
    function setSwapFee(uint256 _swapFee) onlyController external {
        emit SwapFeeSet(msg.sender, _swapFee);
        lpbs().bPool.setSwapFee(_swapFee);
    }

    /** 
        @notice Mints pool shares in exchange for underlying assets
        @param _amount Amount of pool shares to mint
    */
    function joinPool(uint256 _amount) external override virtual ready {
        _joinPool(_amount);
    }

    /**
        @notice Internal join pool function. See joinPool for more info
        @param _amount Amount of pool shares to mint
    */
    function _joinPool(uint256 _amount) internal virtual ready {
        IBPool bPool = lpbs().bPool;
        uint poolTotal = totalSupply();
        uint ratio = bdiv(_amount, poolTotal);
        require(ratio != 0);

        address[] memory tokens = bPool.getCurrentTokens();

        for (uint i = 0; i < tokens.length; i++) {
            address t = tokens[i];
            uint bal = bPool.getBalance(t);
            uint tokenAmountIn = bmul(ratio, bal);
            emit LOG_JOIN(msg.sender, t, tokenAmountIn);
            _pullUnderlying(t, msg.sender, tokenAmountIn, bal);
        }
        _mintPoolShare(_amount);
        _pushPoolShare(msg.sender, _amount);
        emit PoolJoined(msg.sender, _amount);
    }

    /** 
        @notice Burns pool shares and sends back the underlying assets
        @param _amount Amount of pool tokens to burn
    */
    function exitPool(uint256 _amount) external override ready noReentry {
        IBPool bPool = lpbs().bPool;
        uint poolTotal = totalSupply();
        uint ratio = bdiv(_amount, poolTotal);
        require(ratio != 0);

        _pullPoolShare(msg.sender, _amount);
        _burnPoolShare(_amount);

        address[] memory tokens = bPool.getCurrentTokens();

        for (uint i = 0; i < tokens.length; i++) {
            address t = tokens[i];
            uint bal = bPool.getBalance(t);
            uint tAo = bmul(ratio, bal);
            emit LOG_EXIT(msg.sender, t, tAo);  
            _pushUnderlying(t, msg.sender, tAo, bal);
        }
        emit PoolExited(msg.sender, _amount);
    }

    /**
        @notice Bind a token to the underlying balancer pool. Can only be called by the token binder
        @param _token Token to bind
        @param _balance Amount to bind
        @param _denorm Denormalised weight
    */
    function bind(address _token, uint256 _balance, uint256 _denorm) external onlyTokenBinder {
        IBPool bPool = lpbs().bPool;
        IERC20 token = IERC20(_token);
        token.transferFrom(msg.sender, address(this), _balance);
        token.approve(address(bPool), uint256(-1));
        bPool.bind(_token, _balance, _denorm);
    }

    /**
        @notice Rebind a token to the pool
        @param _token Token to bind
        @param _balance Amount to bind
        @param _denorm Denormalised weight
    */
    function rebind(address _token, uint256 _balance, uint256 _denorm) external onlyTokenBinder {
        IBPool bPool = lpbs().bPool;
        IERC20 token = IERC20(_token);
        
        // gulp old non acounted for token balance in the contract
        bPool.gulp(_token);

        uint256 oldBalance = token.balanceOf(address(bPool));
        // If tokens need to be pulled from msg.sender
        if(_balance > oldBalance) {
            token.transferFrom(msg.sender, address(this), bsub(_balance, oldBalance));
            token.approve(address(bPool), uint256(-1));
        }

        bPool.rebind(_token, _balance, _denorm);

        // If any tokens are in this contract send them to msg.sender
        uint256 tokenBalance = token.balanceOf(address(this));
        if(tokenBalance > 0) {
            token.transfer(msg.sender, tokenBalance);
        }
    }

    /**
        @notice Unbind a token
        @param _token Token to unbind
    */
    function unbind(address _token) external onlyTokenBinder {
        IBPool bPool = lpbs().bPool;
        IERC20 token = IERC20(_token);
        // unbind the token in the bPool
        bPool.unbind(_token);

        // If any tokens are in this contract send them to msg.sender
        uint256 tokenBalance = token.balanceOf(address(this));
        if(tokenBalance > 0) {
            token.transfer(msg.sender, tokenBalance);
        }
    }

    function getTokens() external view override returns(address[] memory) {
        return lpbs().bPool.getCurrentTokens();
    }

    /**
        @notice Gets the underlying assets and amounts to mint specific pool shares.
        @param _amount Amount of pool shares to calculate the values for
        @return tokens The addresses of the tokens
        @return amounts The amounts of tokens needed to mint that amount of pool shares
    */
    function calcTokensForAmount(uint256 _amount) external view override returns(address[] memory tokens, uint256[] memory amounts) {
        tokens = lpbs().bPool.getCurrentTokens();
        amounts = new uint256[](tokens.length);
        uint256 ratio = bdiv(_amount, totalSupply());

        for(uint256 i = 0; i < tokens.length; i ++) {
            address t = tokens[i];
            uint256 bal = lpbs().bPool.getBalance(t);
            uint256 amount = bmul(ratio, bal);
            amounts[i] = amount;
        }
    }

    /** 
        @notice Get the address of the controller
        @return The address of the pool
    */
    function getController() external view override returns(address) {
        return lpbs().controller;
    }

    /** 
        @notice Get the address of the public swap setter
        @return The public swap setter address
    */
    function getPublicSwapSetter() external view returns(address) {
        return lpbs().publicSwapSetter;
    }

    /**
        @notice Get the address of the token binder
        @return The token binder address
    */
    function getTokenBinder() external view returns(address) {
        return lpbs().tokenBinder;
    }

    /**
        @notice Get if public swapping is enabled
        @return If public swapping is enabled
    */
    function isPublicSwap() external view returns (bool) {
        return lpbs().bPool.isPublicSwap();
    }

    /**
        @notice Get the current swap fee
        @return The current swap fee
    */
    function getSwapFee() external view returns (uint256) {
        return lpbs().bPool.getSwapFee();
    }

    /**
        @notice Get the address of the underlying Balancer pool
        @return The address of the underlying balancer pool
    */
    function getBPool() external view returns(address) {
        return address(lpbs().bPool);
    }

    /**
        @notice Pull the underlying token from an address and rebind it to the balancer pool
        @param _token Address of the token to pull
        @param _from Address to pull the token from
        @param _amount Amount of token to pull
        @param _tokenBalance Balance of the token already in the balancer pool
    */
    function _pullUnderlying(address _token, address _from, uint256 _amount, uint256 _tokenBalance)
        internal
    {   
        IBPool bPool = lpbs().bPool;
        // Gets current Balance of token i, Bi, and weight of token i, Wi, from BPool.
        uint tokenWeight = bPool.getDenormalizedWeight(_token);

        bool xfer = IERC20(_token).transferFrom(_from, address(this), _amount);
        require(xfer, "ERR_ERC20_FALSE");
        bPool.rebind(_token, badd(_tokenBalance, _amount), tokenWeight);
    }

    /** 
        @notice Push a underlying token and rebind the token to the balancer pool
        @param _token Address of the token to push
        @param _to Address to pull the token to
        @param _amount Amount of token to push
        @param _tokenBalance Balance of the token already in the balancer pool
    */
    function _pushUnderlying(address _token, address _to, uint256 _amount, uint256 _tokenBalance)
        internal
    {   
        IBPool bPool = lpbs().bPool;
        // Gets current Balance of token i, Bi, and weight of token i, Wi, from BPool.
        uint tokenWeight = bPool.getDenormalizedWeight(_token);
        bPool.rebind(_token, bsub(_tokenBalance, _amount), tokenWeight);

        bool xfer = IERC20(_token).transfer(_to, _amount);
        require(xfer, "ERR_ERC20_FALSE");
    }

    /**
        @notice Pull pool shares
        @param _from Address to pull pool shares from
        @param _amount Amount of pool shares to pull
    */
    function _pullPoolShare(address _from, uint256 _amount)
        internal
    {
        _pull(_from, _amount);
    }

    /**
        @notice Burn pool shares
        @param _amount Amount of pool shares to burn
    */
    function _burnPoolShare(uint256 _amount)
        internal
    {
        _burn(_amount);
    }

    /** 
        @notice Mint pool shares 
        @param _amount Amount of pool shares to mint
    */
    function _mintPoolShare(uint256 _amount)
        internal
    {
        _mint(_amount);
    }

    /**
        @notice Push pool shares to account
        @param _to Address to push the pool shares to
        @param _amount Amount of pool shares to push
    */
    function _pushPoolShare(address _to, uint256 _amount)
        internal
    {
        _push(_to, _amount);
    }

    /**
        @notice Load PBasicPool storage
        @return s Pointer to the storage struct
    */
    function lpbs() internal pure returns (pbs storage s) {
        bytes32 loc = pbsSlot;
        assembly {
            s_slot := loc
        }
    }

}


// File contracts/smart-pools/PCappedSmartPool.sol

pragma solidity ^0.6.4;

contract PCappedSmartPool is PBasicSmartPool {

    bytes32 constant public pcsSlot = keccak256("PCappedSmartPool.storage.location");

    event CapChanged(address indexed setter, uint256 oldCap, uint256 newCap);

    struct pcs {
        uint256 cap;
    }

    modifier withinCap() {
        _;
        require(totalSupply() < lpcs().cap, "PCappedSmartPool.withinCap: Cap limit reached");
    }

    /**
        @notice Set the maximum cap of the contract
        @param _cap New cap in wei
    */
    function setCap(uint256 _cap) onlyController external {
        emit CapChanged(msg.sender, lpcs().cap, _cap);
        lpcs().cap = _cap;
    }

    /**
        @notice Takes underlying assets and mints smart pool tokens. Enforces the cap
        @param _amount Amount of pool tokens to mint
    */
    function joinPool(uint256 _amount) external override withinCap {
        super._joinPool(_amount);
    }


    /**
        @notice Get the current cap
        @return The current cap in wei
    */
    function getCap() external view returns(uint256) {
        return lpcs().cap;
    }

    /**
        @notice Load the PCappedSmartPool storage
        @return s Pointer to the storage struct
    */
    function lpcs() internal pure returns (pcs storage s) {
        bytes32 loc = pcsSlot;
        assembly {
            s_slot := loc
        }
    }

}


// File contracts/factory/PProxiedFactory.sol

pragma solidity ^0.6.4;







contract PProxiedFactory is Ownable {

    IBFactory public balancerFactory;
    address public smartPoolImplementation;
    mapping(address => bool) public isPool;
    address[] public pools;

    event SmartPoolCreated(address indexed poolAddress, string name, string symbol);

    function init(address _balancerFactory) public {
        require(smartPoolImplementation == address(0), "Already initialised");
        _setOwner(msg.sender);
        balancerFactory = IBFactory(_balancerFactory);
        
        PCappedSmartPool implementation = new PCappedSmartPool();
        // function init(address _bPool, string calldata _name, string calldata _symbol, uint256 _initialSupply) external {
        implementation.init(address(0), "IMPL", "IMPL", 1 ether);
        smartPoolImplementation = address(implementation);
    }

    function newProxiedSmartPool(
        string memory _name, 
        string memory _symbol,
        uint256 _initialSupply,
        address[] memory _tokens,
        uint256[] memory _amounts,
        uint256[] memory _weights,
        uint256 _cap
    ) public onlyOwner returns(address) {
        // Deploy proxy contract
        PProxyPausable proxy = new PProxyPausable();
        
        // Setup proxy
        proxy.setImplementation(smartPoolImplementation);
        proxy.setPauzer(msg.sender);
        proxy.setProxyOwner(msg.sender); 
        
        // Setup balancer pool
        address balancerPoolAddress = balancerFactory.newBPool();
        IBPool bPool = IBPool(balancerPoolAddress);

        for(uint256 i = 0; i < _tokens.length; i ++) {
            IERC20 token = IERC20(_tokens[i]);
            // Transfer tokens to this contract
            token.transferFrom(msg.sender, address(this), _amounts[i]);
            // Approve the balancer pool
            token.approve(balancerPoolAddress, uint256(-1));
            // Bind tokens
            bPool.bind(_tokens[i], _amounts[i], _weights[i]);
        }
        bPool.setController(address(proxy));
        
        // Setup smart pool
        PCappedSmartPool smartPool = PCappedSmartPool(address(proxy));
    
        smartPool.init(balancerPoolAddress, _name, _symbol, _initialSupply);
        smartPool.setCap(_cap);
        smartPool.setPublicSwapSetter(msg.sender);
        smartPool.setTokenBinder(msg.sender);
        smartPool.setController(msg.sender);
        smartPool.approveTokens();
        
        isPool[address(smartPool)] = true;
        pools.push(address(smartPool));

        emit SmartPoolCreated(address(smartPool), _name, _symbol);

        smartPool.transfer(msg.sender, _initialSupply);

        return address(smartPool);
    }

}


// File contracts/interfaces/IUniswapFactory.sol

pragma solidity ^0.6.4;

interface IUniswapFactory {
    // Create Exchange
    function createExchange(address token) external returns (address exchange);
    // Get Exchange and Token Info
    function getExchange(address token) external view returns (address exchange);
    function getToken(address exchange) external view returns (address token);
    function getTokenWithId(uint256 tokenId) external view returns (address token);
    // Never use
    function initializeFactory(address template) external;
}


// File contracts/interfaces/IUniswapExchange.sol

pragma solidity ^0.6.4;

interface IUniswapExchange {
    // Address of ERC20 token sold on this exchange
    function tokenAddress() external view returns (address token);
    // Address of Uniswap Factory
    function factoryAddress() external view returns (address factory);
    // Provide Liquidity
    function addLiquidity(uint256 min_liquidity, uint256 max_tokens, uint256 deadline) external payable returns (uint256);
    function removeLiquidity(uint256 amount, uint256 min_eth, uint256 min_tokens, uint256 deadline) external returns (uint256, uint256);
    // Get Prices
    function getEthToTokenInputPrice(uint256 eth_sold) external view returns (uint256 tokens_bought);
    function getEthToTokenOutputPrice(uint256 tokens_bought) external view returns (uint256 eth_sold);
    function getTokenToEthInputPrice(uint256 tokens_sold) external view returns (uint256 eth_bought);
    function getTokenToEthOutputPrice(uint256 eth_bought) external view returns (uint256 tokens_sold);
    // Trade ETH to ERC20
    function ethToTokenSwapInput(uint256 min_tokens, uint256 deadline) external payable returns (uint256  tokens_bought);
    function ethToTokenTransferInput(uint256 min_tokens, uint256 deadline, address recipient) external payable returns (uint256  tokens_bought);
    function ethToTokenSwapOutput(uint256 tokens_bought, uint256 deadline) external payable returns (uint256  eth_sold);
    function ethToTokenTransferOutput(uint256 tokens_bought, uint256 deadline, address recipient) external payable returns (uint256  eth_sold);
    // Trade ERC20 to ETH
    function tokenToEthSwapInput(uint256 tokens_sold, uint256 min_eth, uint256 deadline) external returns (uint256  eth_bought);
    function tokenToEthTransferInput(uint256 tokens_sold, uint256 min_eth, uint256 deadline, address recipient) external returns (uint256  eth_bought);
    function tokenToEthSwapOutput(uint256 eth_bought, uint256 max_tokens, uint256 deadline) external returns (uint256  tokens_sold);
    function tokenToEthTransferOutput(uint256 eth_bought, uint256 max_tokens, uint256 deadline, address recipient) external returns (uint256  tokens_sold);
    // Trade ERC20 to ERC20
    function tokenToTokenSwapInput(uint256 tokens_sold, uint256 min_tokens_bought, uint256 min_eth_bought, uint256 deadline, address token_addr) external returns (uint256  tokens_bought);
    function tokenToTokenTransferInput(uint256 tokens_sold, uint256 min_tokens_bought, uint256 min_eth_bought, uint256 deadline, address recipient, address token_addr) external returns (uint256  tokens_bought);
    function tokenToTokenSwapOutput(uint256 tokens_bought, uint256 max_tokens_sold, uint256 max_eth_sold, uint256 deadline, address token_addr) external returns (uint256  tokens_sold);
    function tokenToTokenTransferOutput(uint256 tokens_bought, uint256 max_tokens_sold, uint256 max_eth_sold, uint256 deadline, address recipient, address token_addr) external returns (uint256  tokens_sold);
    // Trade ERC20 to Custom Pool
    function tokenToExchangeSwapInput(uint256 tokens_sold, uint256 min_tokens_bought, uint256 min_eth_bought, uint256 deadline, address exchange_addr) external returns (uint256  tokens_bought);
    function tokenToExchangeTransferInput(uint256 tokens_sold, uint256 min_tokens_bought, uint256 min_eth_bought, uint256 deadline, address recipient, address exchange_addr) external returns (uint256  tokens_bought);
    function tokenToExchangeSwapOutput(uint256 tokens_bought, uint256 max_tokens_sold, uint256 max_eth_sold, uint256 deadline, address exchange_addr) external returns (uint256  tokens_sold);
    function tokenToExchangeTransferOutput(uint256 tokens_bought, uint256 max_tokens_sold, uint256 max_eth_sold, uint256 deadline, address recipient, address exchange_addr) external returns (uint256  tokens_sold);
    // ERC20 comaptibility for liquidity tokens
    // bytes32 public name;
    // bytes32 public symbol;
    // uint256 public decimals;
    function transfer(address _to, uint256 _value) external returns (bool);
    function transferFrom(address _from, address _to, uint256 value) external returns (bool);
    function approve(address _spender, uint256 _value) external returns (bool);
    function allowance(address _owner, address _spender) external view returns (uint256);
    function balanceOf(address _owner) external view returns (uint256);
    function totalSupply() external view returns (uint256);
    // Never use
    function setup(address token_addr) external;
}


// File contracts/recipes/PUniswapPoolRecipe.sol

pragma solidity ^0.6.4;





// Takes ETH and mints smart pool tokens
contract PUniswapPoolRecipe {
    
    bytes32 constant public uprSlot = keccak256("PUniswapPoolRecipe.storage.location");

    // Uniswap pool recipe struct
    struct uprs {
        IPSmartPool pool;
        IUniswapFactory uniswapFactory;
    }

    function init(address _pool, address _uniswapFactory) public virtual {
        uprs storage s = luprs();
        require(address(s.pool) == address(0), "already initialised");
        s.pool = IPSmartPool(_pool);
        s.uniswapFactory = IUniswapFactory(_uniswapFactory);
    }

    // Using same interface as Uniswap for compatibility
    function ethToTokenTransferOutput(uint256 _tokens_bought, uint256 _deadline, address _recipient) public payable returns (uint256  eth_sold) {
        uprs storage s = luprs();
        require(_deadline >= block.timestamp);
        (address[] memory tokens, uint256[] memory amounts) = s.pool.calcTokensForAmount(_tokens_bought);

        eth_sold = 0;
        // Buy and approve tokens
        for(uint256 i = 0; i < tokens.length; i ++) {
            eth_sold += _ethToToken(tokens[i], amounts[i]);
            IERC20(tokens[i]).approve(address(s.pool), uint256(-1));
        }

        // Calculate amount of eth sold
        eth_sold = msg.value - address(this).balance;
        // Send back excess eth
        msg.sender.transfer(address(this).balance);

        // Join pool
        s.pool.joinPool(_tokens_bought);

        // Send pool tokens to receiver
        s.pool.transfer(_recipient, s.pool.balanceOf(address(this)));
        return eth_sold;
    }

    function ethToTokenSwapOutput(uint256 _tokens_bought, uint256 _deadline) external payable returns (uint256 eth_sold) {
        return ethToTokenTransferOutput(_tokens_bought, _deadline, msg.sender);
    }

    function _ethToToken(address _token, uint256 _tokens_bought) internal virtual returns (uint256) {
        uprs storage s = luprs();
        IUniswapExchange exchange = IUniswapExchange(s.uniswapFactory.getExchange(_token));
        return exchange.ethToTokenSwapOutput{value: address(this).balance}(_tokens_bought, uint256(-1));
    }

    function getEthToTokenOutputPrice(uint256 _tokens_bought) external view virtual returns (uint256 eth_sold) {
        uprs storage s = luprs();
        (address[] memory tokens, uint256[] memory amounts) = s.pool.calcTokensForAmount(_tokens_bought);

        eth_sold = 0;

        for(uint256 i = 0; i < tokens.length; i ++) {
            IUniswapExchange exchange = IUniswapExchange(s.uniswapFactory.getExchange(tokens[i]));
            eth_sold += exchange.getEthToTokenOutputPrice(amounts[i]);
        }

        return eth_sold;
    }

    function tokenToEthTransferInput(uint256 _tokens_sold, uint256 _min_eth, uint256 _deadline, address _recipient) public returns (uint256 eth_bought) {
        uprs storage s = luprs();
        require(_deadline >= block.timestamp);
        require(s.pool.transferFrom(msg.sender, address(this), _tokens_sold), "PUniswapPoolRecipe.tokenToEthTransferInput: transferFrom failed");

        s.pool.exitPool(_tokens_sold);

        address[] memory tokens = s.pool.getTokens();

        uint256 ethAmount = 0;

        for(uint256 i = 0; i < tokens.length; i ++) {
            IERC20 token = IERC20(tokens[i]);
            
            uint256 balance = token.balanceOf(address(this));
           
            // Exchange for ETH
            ethAmount += _tokenToEth(token, balance, _recipient);
        }

        require(ethAmount > _min_eth, "PUniswapPoolRecipe.tokenToEthTransferInput: not enough ETH");
        return ethAmount;
    }

    function tokenToEthSwapInput(uint256 _tokens_sold, uint256 _min_eth, uint256 _deadline) external returns (uint256 eth_bought) {
        return tokenToEthTransferInput(_tokens_sold, _min_eth, _deadline, msg.sender);
    }

    function _tokenToEth(IERC20 _token, uint256 _tokens_sold, address _recipient) internal virtual returns (uint256 eth_bought) {
        uprs storage s = luprs();
        IUniswapExchange exchange = IUniswapExchange(s.uniswapFactory.getExchange(address(_token)));
        _token.approve(address(exchange), _tokens_sold);
        // Exchange for ETH
        return exchange.tokenToEthTransferInput(_tokens_sold, 1, uint256(-1), _recipient);
    }

    function getTokenToEthInputPrice(uint256 _tokens_sold) external view virtual returns (uint256 eth_bought) {
        uprs storage s = luprs();
        (address[] memory tokens, uint256[] memory amounts) = s.pool.calcTokensForAmount(_tokens_sold);

        eth_bought = 0;

        for(uint256 i = 0; i < tokens.length; i ++) {
            IUniswapExchange exchange = IUniswapExchange(s.uniswapFactory.getExchange(address(tokens[i])));
            eth_bought += exchange.getTokenToEthInputPrice(amounts[i]);
        }

        return eth_bought;
    }

    function pool() external view returns (address) {
        return address(luprs().pool);
    }

    receive() external payable {

    }

    // Load uniswap pool recipe
    function luprs() internal pure returns (uprs storage s) {
        bytes32 loc = uprSlot;
        assembly {
            s_slot := loc
        }
    }
}


// File contracts/interfaces/IKyberNetwork.sol

pragma solidity ^0.6.4;

interface IKyberNetwork {

    function trade(
        address src,
        uint srcAmount,
        address dest,
        address payable destAddress,
        uint maxDestAmount,
        uint minConversionRate,
        address walletId
    ) external payable returns(uint256);
}


// File contracts/recipes/PUniswapKyberPoolRecipe.sol

pragma solidity ^0.6.4;




contract PUniswapKyberPoolRecipe is PUniswapPoolRecipe, Ownable {

    bytes32 constant public ukprSlot = keccak256("PUniswapKyberPoolRecipe.storage.location");

    // Uniswap pool recipe struct
    struct ukprs {
        mapping(address => bool) swapOnKyber;
        IKyberNetwork kyber;
        address feeReceiver;
    }

    address public constant ETH = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;
    
    function init(address, address) public override {
        require(false, "not enabled");
    }

    // Use seperate init function
    function initUK(address _pool, address _uniswapFactory, address _kyber, address[] memory _swapOnKyber, address _feeReciever) public {
        // UnsiwapRecipe enforces that init can only be called once
        ukprs storage s = lukprs();

        PUniswapPoolRecipe.init(_pool, _uniswapFactory);
        s.kyber = IKyberNetwork(_kyber);
        s.feeReceiver = _feeReciever;

        _setOwner(msg.sender);

        for(uint256 i = 0; i < _swapOnKyber.length; i ++) {
            s.swapOnKyber[_swapOnKyber[i]] = true;
        }
    }

    function setKyberSwap(address _token, bool _value) external onlyOwner {
        ukprs storage s = lukprs();
        s.swapOnKyber[_token] = _value;
    }

    function _ethToToken(address _token, uint256 _tokens_bought) internal override returns (uint256) {
        ukprs storage s = lukprs();
        if(!s.swapOnKyber[_token]) {
            return super._ethToToken(_token, _tokens_bought);
        }

        uint256 ethBefore = address(this).balance;
        s.kyber.trade{value: address(this).balance}(ETH, address(this).balance, _token, address(this), _tokens_bought, 1, s.feeReceiver);
        uint256 ethAfter = address(this).balance;

        // return amount of ETH spend
        return ethBefore - ethAfter;
    }

    function _tokenToEth(IERC20 _token, uint256 _tokens_sold, address _recipient) internal override returns (uint256 eth_bought) {
        ukprs storage s = lukprs();
        if(!s.swapOnKyber[address(_token)]) {
            return super._tokenToEth(_token, _tokens_sold, _recipient);
        }

        uint256 ethBefore = address(this).balance;
        _token.approve(address(s.kyber), uint256(-1));
        s.kyber.trade(address(_token), _tokens_sold, ETH, address(this), uint256(-1), 1, s.feeReceiver);
        uint256 ethAfter = address(this).balance;

        // return amount of ETH received
        return ethAfter - ethBefore;
    }

    // Load uniswap pool recipe
    function lukprs() internal pure returns (ukprs storage s) {
        bytes32 loc = ukprSlot;
        assembly {
            s_slot := loc
        }
    }

}


// File contracts/test/TestReentryProtection.sol

pragma solidity ^0.6.4;


contract TestReentryProtection is ReentryProtection {

    // This should fail
    function test() external noReentry {
        reenter();
    }

    function reenter() public noReentry {
        // Do nothing
    }

}

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"stateMutability":"payable","type":"fallback"},{"inputs":[{"internalType":"address","name":"_value","type":"address"}],"name":"addressToBytes32","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_value","type":"bytes32"}],"name":"bytes32ToAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_value","type":"bytes32"}],"name":"bytes32ToString","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"getImplementation","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getPaused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getPauzer","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getProxyOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_key","type":"bytes32"}],"name":"readAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_key","type":"bytes32"}],"name":"readBool","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_key","type":"bytes32"}],"name":"readString","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renouncePauzer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newImplementation","type":"address"}],"name":"setImplementation","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_value","type":"bool"}],"name":"setPaused","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newPauzer","type":"address"}],"name":"setPauzer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newOwner","type":"address"}],"name":"setProxyOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_key","type":"bytes32"}],"name":"storageRead","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"_value","type":"string"}],"name":"stringToBytes32","outputs":[{"internalType":"bytes32","name":"result","type":"bytes32"}],"stateMutability":"pure","type":"function"}]

608060405234801561001057600080fd5b5061005460405160200180806913d5d3915497d4d313d560b21b815250600a019050604051602081830303815290604052805190602001203361009d60201b60201c565b61009860405160200180806a14105556915497d4d313d560aa1b815250600b019050604051602081830303815290604052805190602001203361009d60201b60201c565b6100d5565b6100c1826100b3836001600160e01b036100c516565b6001600160e01b036100d116565b5050565b6001600160a01b031690565b9055565b610d2d806100e46000396000f3fe6080604052600436106100fe5760003560e01c806382c947b711610095578063aaf10f4211610064578063aaf10f4214610377578063bb15ac8e1461038c578063caaee91c146103b6578063cfb51928146103e9578063d784d4261461049c576100fe565b806382c947b7146102bd5780638f4edfe2146102f05780639201de55146103235780639d84ae691461034d576100fe565b806337a440e6116100d157806337a440e6146102195780634bde4b2e146102555780635ced058e1461026a5780636805b84b14610294576100fe565b806316c38b3c1461010857806317b857dd146101345780631ab7710d146101495780631bc289601461017a575b6101066104cf565b005b34801561011457600080fd5b506101066004803603602081101561012b57600080fd5b50351515610552565b34801561014057600080fd5b5061010661061f565b34801561015557600080fd5b5061015e6106ea565b604080516001600160a01b039092168252519081900360200190f35b34801561018657600080fd5b506101a46004803603602081101561019d57600080fd5b503561072d565b6040805160208082528351818301528351919283929083019185019080838360005b838110156101de5781810151838201526020016101c6565b50505050905090810190601f16801561020b5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561022557600080fd5b506102436004803603602081101561023c57600080fd5b5035610748565b60408051918252519081900360200190f35b34801561026157600080fd5b5061015e61074c565b34801561027657600080fd5b5061015e6004803603602081101561028d57600080fd5b503561078b565b3480156102a057600080fd5b506102a961078e565b604080519115158252519081900360200190f35b3480156102c957600080fd5b50610243600480360360208110156102e057600080fd5b50356001600160a01b03166107cd565b3480156102fc57600080fd5b506101066004803603602081101561031357600080fd5b50356001600160a01b03166107d9565b34801561032f57600080fd5b506101a46004803603602081101561034657600080fd5b50356108a2565b34801561035957600080fd5b5061015e6004803603602081101561037057600080fd5b50356109a7565b34801561038357600080fd5b5061015e6109ba565b34801561039857600080fd5b506102a9600480360360208110156103af57600080fd5b5035610a01565b3480156103c257600080fd5b50610106600480360360208110156103d957600080fd5b50356001600160a01b0316610a15565b3480156103f557600080fd5b506102436004803603602081101561040c57600080fd5b81019060208101813564010000000081111561042757600080fd5b82018360208201111561043957600080fd5b8035906020019184600183028401116401000000008311171561045b57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550610add945050505050565b3480156104a857600080fd5b50610106600480360360208110156104bf57600080fd5b50356001600160a01b0316610afb565b61050c60405160200180806a14105554d15117d4d313d560aa1b815250600b01905060405160208183030381529060405280519060200120610a01565b156105485760405162461bcd60e51b815260040180806020018281038252602c815260200180610ccc602c913960400191505060405180910390fd5b610550610bcc565b565b61058f60405160200180806a14105556915497d4d313d560aa1b815250600b019050604051602081830303815290604052805190602001206109a7565b6001600160a01b0316336001600160a01b0316146105de5760405162461bcd60e51b8152600401808060200182810382526030815260200180610c716030913960400191505060405180910390fd5b61061c60405160200180806a14105554d15117d4d313d560aa1b815250600b0190506040516020818303038152906040528051906020012082610c3a565b50565b61065c60405160200180806a14105556915497d4d313d560aa1b815250600b019050604051602081830303815290604052805190602001206109a7565b6001600160a01b0316336001600160a01b0316146106ab5760405162461bcd60e51b8152600401808060200182810382526030815260200180610c716030913960400191505060405180910390fd5b61055060405160200180806a14105556915497d4d313d560aa1b815250600b019050604051602081830303815290604052805190602001206000610c5f565b600061072860405160200180806913d5d3915497d4d313d560b21b815250600a019050604051602081830303815290604052805190602001206109a7565b905090565b606061074061073b83610748565b6108a2565b90505b919050565b5490565b600061072860405160200180806a14105556915497d4d313d560aa1b815250600b019050604051602081830303815290604052805190602001206109a7565b90565b600061072860405160200180806a14105554d15117d4d313d560aa1b815250600b01905060405160208183030381529060405280519060200120610a01565b6001600160a01b031690565b61081560405160200180806913d5d3915497d4d313d560b21b815250600a019050604051602081830303815290604052805190602001206109a7565b6001600160a01b0316336001600160a01b0316146108645760405162461bcd60e51b815260040180806020018281038252602b815260200180610ca1602b913960400191505060405180910390fd5b61061c60405160200180806a14105556915497d4d313d560aa1b815250600b0190506040516020818303038152906040528051906020012082610c5f565b6040805160208082528183019092526060918291906020820181803683370190505090506000805b6020811015610920576008810260020a85026001600160f81b031981161561091757808484815181106108f957fe5b60200101906001600160f81b031916908160001a9053506001909201915b506001016108ca565b506060816040519080825280601f01601f19166020018201604052801561094e576020820181803683370190505b50905060005b8281101561099e5783818151811061096857fe5b602001015160f81c60f81b82828151811061097f57fe5b60200101906001600160f81b031916908160001a905350600101610954565b50949350505050565b60006107406109b583610748565b61078b565b600061072860405160200180807212535413115351539510551253d397d4d313d5606a1b8152506013019050604051602081830303815290604052805190602001206109a7565b60006001610a0e83610748565b1492915050565b610a5160405160200180806913d5d3915497d4d313d560b21b815250600a019050604051602081830303815290604052805190602001206109a7565b6001600160a01b0316336001600160a01b031614610aa05760405162461bcd60e51b815260040180806020018281038252602b815260200180610ca1602b913960400191505060405180910390fd5b61061c60405160200180806913d5d3915497d4d313d560b21b815250600a0190506040516020818303038152906040528051906020012082610c5f565b80516000908290610af2575060009050610743565b50506020015190565b610b3760405160200180806913d5d3915497d4d313d560b21b815250600a019050604051602081830303815290604052805190602001206109a7565b6001600160a01b0316336001600160a01b031614610b865760405162461bcd60e51b815260040180806020018281038252602b815260200180610ca1602b913960400191505060405180910390fd5b61061c60405160200180807212535413115351539510551253d397d4d313d5606a1b81525060130190506040516020818303038152906040528051906020012082610c5f565b6000610c1360405160200180807212535413115351539510551253d397d4d313d5606a1b8152506013019050604051602081830303815290604052805190602001206109a7565b905060405136600082376000803683855af43d806000843e818015610c36578184f35b8184fd5b8015610c5057610c4b826001610c6c565b610c5b565b610c5b826000610c6c565b5050565b610c5b82610c6c836107cd565b905556fe5050726f78795061757361626c652e6f6e6c795061757a65723a206d73672073656e646572206e6f74207061757a65725050726f78792e6f6e6c7950726f78794f776e65723a206d73672073656e646572206e6f74206f776e65725050726f78795061757361626c652e6e6f745061757365643a20636f6e747261637420697320706175736564a2646970667358221220402a3349b51886149d11d3fe7ed7ff4d98a6c6375ecb098e332019cc656fb6d864736f6c63430006040033

Deployed Bytecode

0x6080604052600436106100fe5760003560e01c806382c947b711610095578063aaf10f4211610064578063aaf10f4214610377578063bb15ac8e1461038c578063caaee91c146103b6578063cfb51928146103e9578063d784d4261461049c576100fe565b806382c947b7146102bd5780638f4edfe2146102f05780639201de55146103235780639d84ae691461034d576100fe565b806337a440e6116100d157806337a440e6146102195780634bde4b2e146102555780635ced058e1461026a5780636805b84b14610294576100fe565b806316c38b3c1461010857806317b857dd146101345780631ab7710d146101495780631bc289601461017a575b6101066104cf565b005b34801561011457600080fd5b506101066004803603602081101561012b57600080fd5b50351515610552565b34801561014057600080fd5b5061010661061f565b34801561015557600080fd5b5061015e6106ea565b604080516001600160a01b039092168252519081900360200190f35b34801561018657600080fd5b506101a46004803603602081101561019d57600080fd5b503561072d565b6040805160208082528351818301528351919283929083019185019080838360005b838110156101de5781810151838201526020016101c6565b50505050905090810190601f16801561020b5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561022557600080fd5b506102436004803603602081101561023c57600080fd5b5035610748565b60408051918252519081900360200190f35b34801561026157600080fd5b5061015e61074c565b34801561027657600080fd5b5061015e6004803603602081101561028d57600080fd5b503561078b565b3480156102a057600080fd5b506102a961078e565b604080519115158252519081900360200190f35b3480156102c957600080fd5b50610243600480360360208110156102e057600080fd5b50356001600160a01b03166107cd565b3480156102fc57600080fd5b506101066004803603602081101561031357600080fd5b50356001600160a01b03166107d9565b34801561032f57600080fd5b506101a46004803603602081101561034657600080fd5b50356108a2565b34801561035957600080fd5b5061015e6004803603602081101561037057600080fd5b50356109a7565b34801561038357600080fd5b5061015e6109ba565b34801561039857600080fd5b506102a9600480360360208110156103af57600080fd5b5035610a01565b3480156103c257600080fd5b50610106600480360360208110156103d957600080fd5b50356001600160a01b0316610a15565b3480156103f557600080fd5b506102436004803603602081101561040c57600080fd5b81019060208101813564010000000081111561042757600080fd5b82018360208201111561043957600080fd5b8035906020019184600183028401116401000000008311171561045b57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550610add945050505050565b3480156104a857600080fd5b50610106600480360360208110156104bf57600080fd5b50356001600160a01b0316610afb565b61050c60405160200180806a14105554d15117d4d313d560aa1b815250600b01905060405160208183030381529060405280519060200120610a01565b156105485760405162461bcd60e51b815260040180806020018281038252602c815260200180610ccc602c913960400191505060405180910390fd5b610550610bcc565b565b61058f60405160200180806a14105556915497d4d313d560aa1b815250600b019050604051602081830303815290604052805190602001206109a7565b6001600160a01b0316336001600160a01b0316146105de5760405162461bcd60e51b8152600401808060200182810382526030815260200180610c716030913960400191505060405180910390fd5b61061c60405160200180806a14105554d15117d4d313d560aa1b815250600b0190506040516020818303038152906040528051906020012082610c3a565b50565b61065c60405160200180806a14105556915497d4d313d560aa1b815250600b019050604051602081830303815290604052805190602001206109a7565b6001600160a01b0316336001600160a01b0316146106ab5760405162461bcd60e51b8152600401808060200182810382526030815260200180610c716030913960400191505060405180910390fd5b61055060405160200180806a14105556915497d4d313d560aa1b815250600b019050604051602081830303815290604052805190602001206000610c5f565b600061072860405160200180806913d5d3915497d4d313d560b21b815250600a019050604051602081830303815290604052805190602001206109a7565b905090565b606061074061073b83610748565b6108a2565b90505b919050565b5490565b600061072860405160200180806a14105556915497d4d313d560aa1b815250600b019050604051602081830303815290604052805190602001206109a7565b90565b600061072860405160200180806a14105554d15117d4d313d560aa1b815250600b01905060405160208183030381529060405280519060200120610a01565b6001600160a01b031690565b61081560405160200180806913d5d3915497d4d313d560b21b815250600a019050604051602081830303815290604052805190602001206109a7565b6001600160a01b0316336001600160a01b0316146108645760405162461bcd60e51b815260040180806020018281038252602b815260200180610ca1602b913960400191505060405180910390fd5b61061c60405160200180806a14105556915497d4d313d560aa1b815250600b0190506040516020818303038152906040528051906020012082610c5f565b6040805160208082528183019092526060918291906020820181803683370190505090506000805b6020811015610920576008810260020a85026001600160f81b031981161561091757808484815181106108f957fe5b60200101906001600160f81b031916908160001a9053506001909201915b506001016108ca565b506060816040519080825280601f01601f19166020018201604052801561094e576020820181803683370190505b50905060005b8281101561099e5783818151811061096857fe5b602001015160f81c60f81b82828151811061097f57fe5b60200101906001600160f81b031916908160001a905350600101610954565b50949350505050565b60006107406109b583610748565b61078b565b600061072860405160200180807212535413115351539510551253d397d4d313d5606a1b8152506013019050604051602081830303815290604052805190602001206109a7565b60006001610a0e83610748565b1492915050565b610a5160405160200180806913d5d3915497d4d313d560b21b815250600a019050604051602081830303815290604052805190602001206109a7565b6001600160a01b0316336001600160a01b031614610aa05760405162461bcd60e51b815260040180806020018281038252602b815260200180610ca1602b913960400191505060405180910390fd5b61061c60405160200180806913d5d3915497d4d313d560b21b815250600a0190506040516020818303038152906040528051906020012082610c5f565b80516000908290610af2575060009050610743565b50506020015190565b610b3760405160200180806913d5d3915497d4d313d560b21b815250600a019050604051602081830303815290604052805190602001206109a7565b6001600160a01b0316336001600160a01b031614610b865760405162461bcd60e51b815260040180806020018281038252602b815260200180610ca1602b913960400191505060405180910390fd5b61061c60405160200180807212535413115351539510551253d397d4d313d5606a1b81525060130190506040516020818303038152906040528051906020012082610c5f565b6000610c1360405160200180807212535413115351539510551253d397d4d313d5606a1b8152506013019050604051602081830303815290604052805190602001206109a7565b905060405136600082376000803683855af43d806000843e818015610c36578184f35b8184fd5b8015610c5057610c4b826001610c6c565b610c5b565b610c5b826000610c6c565b5050565b610c5b82610c6c836107cd565b905556fe5050726f78795061757361626c652e6f6e6c795061757a65723a206d73672073656e646572206e6f74207061757a65725050726f78792e6f6e6c7950726f78794f776e65723a206d73672073656e646572206e6f74206f776e65725050726f78795061757361626c652e6e6f745061757365643a20636f6e747261637420697320706175736564a2646970667358221220402a3349b51886149d11d3fe7ed7ff4d98a6c6375ecb098e332019cc656fb6d864736f6c63430006040033

Deployed Bytecode Sourcemap

4708:1253:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4050:18;:16;:18::i;:::-;4708:1253;5744:97;;5:9:-1;2:2;;;27:1;24;17:12;2:2;5744:97:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;5744:97:0;;;;:::i;5535:98::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;5535:98:0;;;:::i;3487:103::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;3487:103:0;;;:::i;:::-;;;;-1:-1:-1;;;;;3487:103:0;;;;;;;;;;;;;;255:129;;5:9:-1;2:2;;;27:1;24;17:12;2:2;255:129:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;255:129:0;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:100:-1;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;255:129:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1141:248;;5:9:-1;2:2;;;27:1;24;17:12;2:2;1141:248:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;1141:248:0;;:::i;:::-;;;;;;;;;;;;;;;;5304:101;;5:9:-1;2:2;;;27:1;24;17:12;2:2;5304:101:0;;;:::i;1711:130::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;1711:130:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;1711:130:0;;:::i;5641:95::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;5641:95:0;;;:::i;:::-;;;;;;;;;;;;;;;;;;1849:121;;5:9:-1;2:2;;;27:1;24;17:12;2:2;1849:121:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;1849:121:0;-1:-1:-1;;;;;1849:121:0;;:::i;5413:114::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;5413:114:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;5413:114:0;-1:-1:-1;;;;;5413:114:0;;:::i;2300:636::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;2300:636:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;2300:636:0;;:::i;880:125::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;880:125:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;880:125:0;;:::i;3722:117::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;3722:117:0;;;:::i;524:124::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;524:124:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;524:124:0;;:::i;3598:116::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;3598:116:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;3598:116:0;-1:-1:-1;;;;;3598:116:0;;:::i;1978:314::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;1978:314:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;1978:314:0;;;;;;;;27:11:-1;11:28;;8:2;;;52:1;49;42:12;8:2;1978:314:0;;41:9:-1;34:4;18:14;14:25;11:40;8:2;;;64:1;61;54:12;8:2;1978:314:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;39:11;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;1978:314:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;1978:314:0;;-1:-1:-1;1978:314:0;;-1:-1:-1;;;;;1978:314:0:i;3847:147::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;3847:147:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;3847:147:0;-1:-1:-1;;;;;3847:147:0;;:::i;5849:107::-;5206:21;4792:31;;;;;;-1:-1:-1;;;4792:31:0;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;4792:31:0;;;4782:42;;;;;;5206:8;:21::i;:::-;5205:22;5197:79;;;;-1:-1:-1;;;5197:79:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5924:24:::1;:22;:24::i;:::-;5849:107::o:0;5744:97::-;5060:24;4872:31;;;;;;-1:-1:-1;;;4872:31:0;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;4872:31:0;;;4862:42;;;;;;5060:11;:24::i;:::-;-1:-1:-1;;;;;5046:38:0;:10;:38;5038:99;;;;-1:-1:-1;;;5038:99:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5805:28:::1;4792:31;;;;;;-1:-1:-1::0;;;4792:31:0::1;;::::0;::::1;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;4792:31:0;;;4782:42;;;;;;5826:6;5805:7;:28::i;:::-;5744:97:::0;:::o;5535:98::-;5060:24;4872:31;;;;;;-1:-1:-1;;;4872:31:0;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;4872:31:0;;;4862:42;;;;;;5060:11;:24::i;:::-;-1:-1:-1;;;;;5046:38:0;:10;:38;5038:99;;;;-1:-1:-1;;;5038:99:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5590:35:::1;4872:31;;;;;;-1:-1:-1::0;;;4872:31:0::1;;::::0;::::1;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;4872:31:0;;;4862:42;;;;;;5622:1;5590:10;:35::i;3487:103::-:0;3533:7;3559:23;3206:30;;;;;;-1:-1:-1;;;3206:30:0;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;3206:30:0;;;3196:41;;;;;;3559:11;:23::i;:::-;3552:30;;3487:103;:::o;255:129::-;309:13;342:34;358:17;370:4;358:11;:17::i;:::-;342:15;:34::i;:::-;335:41;;255:129;;;;:::o;1141:248::-;1337:11;;1141:248::o;5304:101::-;5346:7;5373:24;4872:31;;;;;;-1:-1:-1;;;4872:31:0;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;4872:31:0;;;4862:42;;;;;;5373:11;:24::i;1711:130::-;1824:6;1711:130::o;5641:95::-;5683:4;5707:21;4792:31;;;;;;-1:-1:-1;;;4792:31:0;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;4792:31:0;;;4782:42;;;;;;5707:8;:21::i;1849:121::-;-1:-1:-1;;;;;1946:15:0;;1849:121::o;5413:114::-;3305:23;3206:30;;;;;;-1:-1:-1;;;3206:30:0;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;3206:30:0;;;3196:41;;;;;;3305:11;:23::i;:::-;-1:-1:-1;;;;;3291:37:0;:10;:37;3283:93;;;;-1:-1:-1;;;3283:93:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5484:35:::1;4872:31;;;;;;-1:-1:-1::0;;;4872:31:0::1;;::::0;::::1;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;4872:31:0;;;4862:42;;;;;;5508:10;5484;:35::i;2300:636::-:0;2415:13;;;2425:2;2415:13;;;;;;;;;2362;;;;2415;;;;21:6:-1;;108:14;2415:13:0;87:42:-1;143:17;;-1:-1;;2388:40:0;-1:-1:-1;2439:14:0;;2468:237;2492:2;2488:1;:6;2468:237;;;2562:1;:5;;2556:1;:12;2541:27;;-1:-1:-1;;;;;;2589:9:0;;;2585:109;;2644:4;2619:11;2631:9;2619:22;;;;;;;;-1:-1:-1;;;;;;2619:29:0;;;;;;;;;:22;;;:29;-1:-1:-1;2667:11:0;;;;;2585:109;-1:-1:-1;2496:3:0;;2468:237;;;;2715:31;2759:9;2749:20;;;;;;;;;;;;;;;;;;;;;;;;;21:6:-1;;108:14;2749:20:0;87:42:-1;143:17;;-1:-1;2749:20:0;-1:-1:-1;2715:54:0;-1:-1:-1;2785:9:0;2780:105;2804:9;2800:1;:13;2780:105;;;2859:11;2871:1;2859:14;;;;;;;;;;;;;;;;2835:18;2854:1;2835:21;;;;;;;;-1:-1:-1;;;;;;2835:38:0;;;;;;;;;:21;;;:38;-1:-1:-1;2815:3:0;;2780:105;;;-1:-1:-1;2909:18:0;2300:636;-1:-1:-1;;;;2300:636:0:o;880:125::-;935:7;962:35;979:17;991:4;979:11;:17::i;:::-;962:16;:35::i;3722:117::-;3772:7;3799:32;3119:39;;;;;;-1:-1:-1;;;3119:39:0;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;3119:39:0;;;3109:50;;;;;;3799:11;:32::i;524:124::-;576:4;637:1;600:17;612:4;600:11;:17::i;:::-;:40;;524:124;-1:-1:-1;;524:124:0:o;3598:116::-;3305:23;3206:30;;;;;;-1:-1:-1;;;3206:30:0;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;3206:30:0;;;3196:41;;;;;;3305:11;:23::i;:::-;-1:-1:-1;;;;;3291:37:0;:10;:37;3283:93;;;;-1:-1:-1;;;3283:93:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3673:33:::1;3206:30;;;;;;-1:-1:-1::0;;;3206:30:0::1;;::::0;::::1;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;3206:30:0;;;3196:41;;;;;;3696:9;3673:10;:33::i;1978:314::-:0;2136:26;;2046:14;;2114:6;;2132:74;;-1:-1:-1;2191:3:0;;-1:-1:-1;2184:10:0;;2132:74;-1:-1:-1;;2270:2:0;2258:15;2252:22;;2227:58::o;3847:147::-;3305:23;3206:30;;;;;;-1:-1:-1;;;3206:30:0;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;3206:30:0;;;3196:41;;;;;;3305:11;:23::i;:::-;-1:-1:-1;;;;;3291:37:0;:10;:37;3283:93;;;;-1:-1:-1;;;3283:93:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3935:51:::1;3119:39;;;;;;-1:-1:-1::0;;;3119:39:0::1;;::::0;::::1;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;3119:39:0;;;3109:50;;;;;;3967:18;3935:10;:51::i;4084:522::-:0;4140:20;4163:32;3119:39;;;;;;-1:-1:-1;;;3119:39:0;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;3119:39:0;;;3109:50;;;;;;4163:11;:32::i;:::-;4140:55;;4247:4;4241:11;4287:14;4284:1;4279:3;4266:36;4388:1;4385;4369:14;4364:3;4350:12;4343:5;4330:60;4416:16;4469:4;4466:1;4461:3;4446:28;4497:6;4517:28;;;;4581:4;4576:3;4569:17;4517:28;4538:4;4533:3;4526:17;656:216;723:6;720:145;;;746:37;757:4;779:1;746:10;:37::i;:::-;720:145;;;816:37;827:4;849:1;816:10;:37::i;:::-;656:216;;:::o;1013:120::-;1083:42;1094:4;1100:24;1117:6;1100:16;:24::i;:::-;1648:37;;1633:63::o

Swarm Source

ipfs://402a3349b51886149d11d3fe7ed7ff4d98a6c6375ecb098e332019cc656fb6d8
Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.