{"file_path":"src/escrows/INVEscrow.sol","creation_status":"success","source_code":"// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.13;\nimport \"../interfaces/IERC20.sol\";\nimport {FixedPointMathLib} from \"solmate/utils/FixedPointMathLib.sol\";\n\n// @dev Caution: We assume all failed transfers cause reverts and ignore the returned bool.\ninterface IXINV {\n    function rewardTreasury() external view returns(address);\n    function balanceOf(address) external view returns (uint);\n    function exchangeRateStored() external view returns (uint);\n    function exchangeRateCurrent() external returns (uint);\n    function mint(uint mintAmount) external returns (uint);\n    function redeemUnderlying(uint redeemAmount) external returns (uint);\n    function syncDelegate(address user) external;\n    function accrualBlockNumber() external view returns (uint);\n    function getCash() external view returns (uint);\n    function totalSupply() external view returns (uint);\n    function rewardPerBlock() external view returns (uint);\n}\n\ninterface IDbrDistributor {\n    function stake(uint amount) external;\n    function unstake(uint amount) external;\n    function claim(address to) external;\n    function claimable(address user) external view returns(uint);\n}\n\n/**\n * @title INV Escrow\n * @notice Collateral is stored in unique escrow contracts for every user and every market.\n * This escrow allows user to deposit INV collateral directly into the xINV contract, earning APY and allowing them to delegate votes on behalf of the xINV collateral\n * @dev Caution: This is a proxy implementation. Follow proxy pattern best practices\n */\ncontract INVEscrow {\n    using FixedPointMathLib for uint;\n\n    address public market;\n    IDelegateableERC20 public token;\n    address public beneficiary;\n    uint public stakedXINV;\n    IXINV public immutable xINV;\n    IDbrDistributor public immutable distributor;\n    mapping(address => bool) public claimers;\n\n    constructor(IXINV _xINV, IDbrDistributor _distributor) {\n        xINV = _xINV;\n        distributor = _distributor;\n    }\n\n    /**\n     * @notice Initialize escrow with a token\n     * @dev Must be called right after proxy is created.\n     * @param _token The IERC20 token representing the INV governance token\n     * @param _beneficiary The beneficiary who may delegate token voting power\n     */\n    function initialize(IDelegateableERC20 _token, address _beneficiary) public {\n        require(market == address(0), \"ALREADY INITIALIZED\");\n        market = msg.sender;\n        token = _token;\n        beneficiary = _beneficiary;\n        _token.delegate(_token.delegates(_beneficiary));\n        _token.approve(address(xINV), type(uint).max);\n        xINV.syncDelegate(address(this));\n    }\n    \n    /**\n     * @notice Transfers the associated ERC20 token to a recipient.\n     * @param recipient The address to receive payment from the escrow\n     * @param amount The amount of ERC20 token to be transferred.\n     */\n    function pay(address recipient, uint amount) public {\n        require(msg.sender == market, \"ONLY MARKET\");\n        uint invBalance = token.balanceOf(address(this));\n        if(invBalance < amount) {\n            uint invNeeded = amount - invBalance;\n            uint xInvToUnstake = invNeeded * 1 ether / viewExchangeRate();\n            stakedXINV -= xInvToUnstake;\n            distributor.unstake(xInvToUnstake);\n            xINV.redeemUnderlying(invNeeded); // we do not check return value because transfer call will fail if this fails anyway\n        }\n        token.transfer(recipient, amount);\n    }\n    \n    /**\n     * @notice Allows the beneficiary to claim DBR tokens\n     * @dev Requires the caller to be the beneficiary\n     */\n    function claimDBR() public {\n        require(msg.sender == beneficiary, \"ONLY BENEFICIARY\");\n        distributor.claim(msg.sender);\n    }\n\n    /**\n     * @notice Allows the beneficiary or allowed claimers to claim DBR tokens on behalf of another address\n     * @param to The address to which the claimed tokens will be sent\n     * @dev Requires the caller to be the beneficiary or an allowed claimer\n     */\n    function claimDBRTo(address to) public {\n        require(msg.sender == beneficiary || claimers[msg.sender], \"ONLY BENEFICIARY OR ALLOWED CLAIMERS\");\n        distributor.claim(to);\n    }\n\n    /**\n     * @notice Returns the amount of claimable DBR tokens for the contract\n     * @return The amount of claimable tokens\n     */\n    function claimable() public view returns (uint) {\n        return distributor.claimable(address(this));\n    }\n\n    /**\n     * @notice Sets or unsets an address as an allowed claimer\n     * @param claimer The address of the claimer to set or unset\n     * @param allowed A boolean value to determine if the claimer is allowed or not\n     * @dev Requires the caller to be the beneficiary\n     */\n    function setClaimer(address claimer, bool allowed) public {\n        require(msg.sender == beneficiary, \"ONLY BENEFICIARY\");\n        claimers[claimer] = allowed;\n    }\n\n    /**\n    * @notice Get the token balance of the escrow\n    * @return Uint representing the INV token balance of the escrow including the additional INV accrued from xINV\n    */\n    function balance() public view returns (uint) {\n        uint invBalance = token.balanceOf(address(this));\n        uint invBalanceInXInv = stakedXINV * viewExchangeRate() / 1 ether;\n        return invBalance + invBalanceInXInv;\n    }\n    \n    /**\n     * @notice Function called by market on deposit. Will deposit INV into xINV \n     * @dev This function should remain callable by anyone to handle direct inbound transfers.\n     */\n    function onDeposit() public {\n        uint invBalance = token.balanceOf(address(this));\n        if(invBalance > 0) {\n            uint xinvBal = xINV.balanceOf(address(this));\n            xINV.mint(invBalance); // we do not check return value because we don't want errors to block this call\n            stakedXINV += xINV.balanceOf(address(this)) - xinvBal;\n            distributor.stake(stakedXINV - xinvBal);\n        }\n    }\n\n    /**\n     * @notice Delegates voting power of the underlying xINV.\n     * @param delegatee The address to be delegated voting power\n     */\n    function delegate(address delegatee) public {\n        require(msg.sender == beneficiary, \"ONLY BENEFICIARY\");\n        token.delegate(delegatee);\n        xINV.syncDelegate(address(this));\n    }\n\n    /**\n     * @notice View function to calculate exact exchangerate for current block\n     */\n    function viewExchangeRate() internal view returns (uint) {\n        uint accrualBlockNumberPrior = xINV.accrualBlockNumber();\n        if (accrualBlockNumberPrior == block.number) return xINV.exchangeRateStored();\n        uint blockDelta = block.number - accrualBlockNumberPrior;\n        uint rewardsAccrued = xINV.rewardPerBlock() * blockDelta;\n        uint treasuryInvBalance = token.balanceOf(xINV.rewardTreasury());\n        uint treasuryxInvAllowance = token.allowance(xINV.rewardTreasury(), address(xINV));\n        if( treasuryInvBalance <= rewardsAccrued || treasuryxInvAllowance <= rewardsAccrued) return xINV.exchangeRateStored();\n        return (xINV.getCash() + rewardsAccrued).divWadDown(xINV.totalSupply());\n    }\n\n}\n","deployed_bytecode":"0x608060405234801561001057600080fd5b50600436106101005760003560e01c8063b69ef8a811610097578063c93f304e11610066578063c93f304e14610213578063da62fba91461021b578063dee607971461024e578063fc0c546a1461026157600080fd5b8063b69ef8a8146101c8578063bdb4b143146101d0578063bfe10928146101d9578063c40768761461020057600080fd5b80635c19a95c116100d35780635c19a95c1461016557806364ee1a311461017857806380f556051461019f578063af38d757146101b257600080fd5b806312c93f591461010557806338af3eed1461010f5780633d4c415a1461013f578063485cc95514610152575b600080fd5b61010d610274565b005b600254610122906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b61010d61014d366004611410565b610541565b61010d610160366004611449565b61059f565b61010d610173366004611477565b6107b9565b6101227f0000000000000000000000001637e4e9941d55703a7a5e7807d6ada3f7dcd61b81565b600054610122906001600160a01b031681565b6101ba6108bf565b604051908152602001610136565b6101ba61094f565b6101ba60035481565b6101227f000000000000000000000000dcd2d918511ba39f2872eb731bb88681ae18424481565b61010d61020e366004611494565b6109ff565b61010d610c91565b61023e610229366004611477565b60046020526000908152604090205460ff1681565b6040519015158152602001610136565b61010d61025c366004611477565b610d30565b600154610122906001600160a01b031681565b6001546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa1580156102bd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102e191906114c0565b9050801561053e576040516370a0823160e01b81523060048201526000907f0000000000000000000000001637e4e9941d55703a7a5e7807d6ada3f7dcd61b6001600160a01b0316906370a0823190602401602060405180830381865afa158015610350573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061037491906114c0565b60405163140e25ad60e31b8152600481018490529091507f0000000000000000000000001637e4e9941d55703a7a5e7807d6ada3f7dcd61b6001600160a01b03169063a0712d68906024016020604051808303816000875af11580156103de573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061040291906114c0565b506040516370a0823160e01b815230600482015281907f0000000000000000000000001637e4e9941d55703a7a5e7807d6ada3f7dcd61b6001600160a01b0316906370a0823190602401602060405180830381865afa158015610469573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061048d91906114c0565b61049791906114ef565b600360008282546104a89190611506565b925050819055507f000000000000000000000000dcd2d918511ba39f2872eb731bb88681ae1842446001600160a01b031663a694fc3a826003546104ec91906114ef565b6040518263ffffffff1660e01b815260040161050a91815260200190565b600060405180830381600087803b15801561052457600080fd5b505af1158015610538573d6000803e3d6000fd5b50505050505b50565b6002546001600160a01b031633146105745760405162461bcd60e51b815260040161056b9061151e565b60405180910390fd5b6001600160a01b03919091166000908152600460205260409020805460ff1916911515919091179055565b6000546001600160a01b0316156105ee5760405162461bcd60e51b815260206004820152601360248201527210531491505116481253925512505312569151606a1b604482015260640161056b565b60008054336001600160a01b0319918216179091556001805482166001600160a01b0385811691821790925560028054909316918416918217909255604051632c3e6f0f60e11b81526004810191909152635c19a95c90829063587cde1e90602401602060405180830381865afa15801561066d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106919190611548565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401600060405180830381600087803b1580156106d257600080fd5b505af11580156106e6573d6000803e3d6000fd5b505060405163095ea7b360e01b81526001600160a01b037f0000000000000000000000001637e4e9941d55703a7a5e7807d6ada3f7dcd61b8116600483015260001960248301528516925063095ea7b39150604401600060405180830381600087803b15801561075557600080fd5b505af1158015610769573d6000803e3d6000fd5b5050604051631e756d0f60e01b81523060048201527f0000000000000000000000001637e4e9941d55703a7a5e7807d6ada3f7dcd61b6001600160a01b03169250631e756d0f915060240161050a565b6002546001600160a01b031633146107e35760405162461bcd60e51b815260040161056b9061151e565b6001546040516317066a5760e21b81526001600160a01b03838116600483015290911690635c19a95c90602401600060405180830381600087803b15801561082a57600080fd5b505af115801561083e573d6000803e3d6000fd5b5050604051631e756d0f60e01b81523060048201527f0000000000000000000000001637e4e9941d55703a7a5e7807d6ada3f7dcd61b6001600160a01b03169250631e756d0f91506024015b600060405180830381600087803b1580156108a457600080fd5b505af11580156108b8573d6000803e3d6000fd5b5050505050565b60405163402914f560e01b81523060048201526000907f000000000000000000000000dcd2d918511ba39f2872eb731bb88681ae1842446001600160a01b03169063402914f590602401602060405180830381865afa158015610926573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061094a91906114c0565b905090565b6001546040516370a0823160e01b815230600482015260009182916001600160a01b03909116906370a0823190602401602060405180830381865afa15801561099c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109c091906114c0565b90506000670de0b6b3a76400006109d5610dfe565b6003546109e29190611565565b6109ec9190611584565b90506109f88183611506565b9250505090565b6000546001600160a01b03163314610a475760405162461bcd60e51b815260206004820152600b60248201526a13d393164813505492d15560aa1b604482015260640161056b565b6001546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa158015610a90573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ab491906114c0565b905081811015610c14576000610aca82846114ef565b90506000610ad6610dfe565b610ae883670de0b6b3a7640000611565565b610af29190611584565b90508060036000828254610b0691906114ef565b90915550506040516305c2fbcf60e31b8152600481018290527f000000000000000000000000dcd2d918511ba39f2872eb731bb88681ae1842446001600160a01b031690632e17de7890602401600060405180830381600087803b158015610b6d57600080fd5b505af1158015610b81573d6000803e3d6000fd5b505060405163852a12e360e01b8152600481018590527f0000000000000000000000001637e4e9941d55703a7a5e7807d6ada3f7dcd61b6001600160a01b0316925063852a12e391506024016020604051808303816000875af1158015610bec573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c1091906114c0565b5050505b60015460405163a9059cbb60e01b81526001600160a01b038581166004830152602482018590529091169063a9059cbb906044016020604051808303816000875af1158015610c67573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c8b91906115a6565b50505050565b6002546001600160a01b03163314610cbb5760405162461bcd60e51b815260040161056b9061151e565b604051630f41a04d60e11b81523360048201527f000000000000000000000000dcd2d918511ba39f2872eb731bb88681ae1842446001600160a01b031690631e83409a90602401600060405180830381600087803b158015610d1c57600080fd5b505af1158015610c8b573d6000803e3d6000fd5b6002546001600160a01b0316331480610d5857503360009081526004602052604090205460ff165b610db05760405162461bcd60e51b8152602060048201526024808201527f4f4e4c592042454e4546494349415259204f5220414c4c4f57454420434c41496044820152634d45525360e01b606482015260840161056b565b604051630f41a04d60e11b81526001600160a01b0382811660048301527f000000000000000000000000dcd2d918511ba39f2872eb731bb88681ae1842441690631e83409a9060240161088a565b6000807f0000000000000000000000001637e4e9941d55703a7a5e7807d6ada3f7dcd61b6001600160a01b0316636c540baf6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610e5f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e8391906114c0565b9050438103610f14577f0000000000000000000000001637e4e9941d55703a7a5e7807d6ada3f7dcd61b6001600160a01b031663182df0f56040518163ffffffff1660e01b8152600401602060405180830381865afa158015610eea573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f0e91906114c0565b91505090565b6000610f2082436114ef565b90506000817f0000000000000000000000001637e4e9941d55703a7a5e7807d6ada3f7dcd61b6001600160a01b0316638ae39cac6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610f83573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fa791906114c0565b610fb19190611565565b90506000600160009054906101000a90046001600160a01b03166001600160a01b03166370a082317f0000000000000000000000001637e4e9941d55703a7a5e7807d6ada3f7dcd61b6001600160a01b031663c7c934a16040518163ffffffff1660e01b8152600401602060405180830381865afa158015611037573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061105b9190611548565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401602060405180830381865afa15801561109f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110c391906114c0565b90506000600160009054906101000a90046001600160a01b03166001600160a01b031663dd62ed3e7f0000000000000000000000001637e4e9941d55703a7a5e7807d6ada3f7dcd61b6001600160a01b031663c7c934a16040518163ffffffff1660e01b8152600401602060405180830381865afa158015611149573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061116d9190611548565b60405160e083901b6001600160e01b03191681526001600160a01b0391821660048201527f0000000000000000000000001637e4e9941d55703a7a5e7807d6ada3f7dcd61b9091166024820152604401602060405180830381865afa1580156111da573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111fe91906114c0565b9050828211158061120f5750828111155b156112a0577f0000000000000000000000001637e4e9941d55703a7a5e7807d6ada3f7dcd61b6001600160a01b031663182df0f56040518163ffffffff1660e01b8152600401602060405180830381865afa158015611272573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061129691906114c0565b9550505050505090565b6112967f0000000000000000000000001637e4e9941d55703a7a5e7807d6ada3f7dcd61b6001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611301573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061132591906114c0565b847f0000000000000000000000001637e4e9941d55703a7a5e7807d6ada3f7dcd61b6001600160a01b0316633b1d21a26040518163ffffffff1660e01b8152600401602060405180830381865afa158015611384573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113a891906114c0565b6113b29190611506565b9060006113c883670de0b6b3a7640000846113cf565b9392505050565b60008260001904841183021582026113e657600080fd5b5091020490565b6001600160a01b038116811461053e57600080fd5b801515811461053e57600080fd5b6000806040838503121561142357600080fd5b823561142e816113ed565b9150602083013561143e81611402565b809150509250929050565b6000806040838503121561145c57600080fd5b8235611467816113ed565b9150602083013561143e816113ed565b60006020828403121561148957600080fd5b81356113c8816113ed565b600080604083850312156114a757600080fd5b82356114b2816113ed565b946020939093013593505050565b6000602082840312156114d257600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b600082821015611501576115016114d9565b500390565b60008219821115611519576115196114d9565b500190565b60208082526010908201526f4f4e4c592042454e454649434941525960801b604082015260600190565b60006020828403121561155a57600080fd5b81516113c8816113ed565b600081600019048311821515161561157f5761157f6114d9565b500290565b6000826115a157634e487b7160e01b600052601260045260246000fd5b500490565b6000602082840312156115b857600080fd5b81516113c88161140256fea2646970667358221220273827ed0840ee4dab603b05cd6aa00bd8974e8055e08ee049ac0d0ca561746264736f6c634300080d0033","optimization_enabled":true,"verified_twin_address_hash":null,"is_verified":true,"compiler_settings":{"evmVersion":"london","libraries":{},"metadata":{"bytecodeHash":"ipfs"},"optimizer":{"enabled":true,"runs":200},"remappings":[":ds-test/=lib/solmate/lib/ds-test/src/",":forge-std/=lib/forge-std/src/",":openzeppelin-contracts/=lib/openzeppelin-contracts/",":solmate/=lib/solmate/src/"]},"optimization_runs":200,"sourcify_repo_url":"https://repo.sourcify.dev/contracts/full_match/1/0x502a7759809bD673cd39A0055beed44b40EAac98/","decoded_constructor_args":[["0x1637e4e9941D55703a7A5E7807d6aDA3f7DCD61B",{"internalType":"contract IXINV","name":"_xINV","type":"address"}],["0xdcd2D918511Ba39F2872EB731BB88681AE184244",{"internalType":"contract IDbrDistributor","name":"_distributor","type":"address"}]],"compiler_version":"0.8.13+commit.abaa5c0e","is_verified_via_verifier_alliance":false,"verified_at":"2024-02-29T20:59:52.393788Z","implementations":[],"proxy_type":null,"external_libraries":[],"creation_bytecode":"0x60c060405234801561001057600080fd5b506040516200174c3803806200174c83398101604081905261003191610060565b6001600160a01b039182166080521660a05261009a565b6001600160a01b038116811461005d57600080fd5b50565b6000806040838503121561007357600080fd5b825161007e81610048565b602084015190925061008f81610048565b809150509250929050565b60805160a0516115f962000153600039600081816101de015281816104b1015281816108d701528181610b2101528181610cd00152610dcf01526000818161017d015281816103010152818161038d0152818161041a015281816106ff015281816107800152818161085501528181610b9901528181610e0301528181610e8e01528181610f2701528181610fdb015281816110ed0152818161119301528181611216015281816112a5015261132801526115f96000f3fe608060405234801561001057600080fd5b50600436106101005760003560e01c8063b69ef8a811610097578063c93f304e11610066578063c93f304e14610213578063da62fba91461021b578063dee607971461024e578063fc0c546a1461026157600080fd5b8063b69ef8a8146101c8578063bdb4b143146101d0578063bfe10928146101d9578063c40768761461020057600080fd5b80635c19a95c116100d35780635c19a95c1461016557806364ee1a311461017857806380f556051461019f578063af38d757146101b257600080fd5b806312c93f591461010557806338af3eed1461010f5780633d4c415a1461013f578063485cc95514610152575b600080fd5b61010d610274565b005b600254610122906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b61010d61014d366004611410565b610541565b61010d610160366004611449565b61059f565b61010d610173366004611477565b6107b9565b6101227f000000000000000000000000000000000000000000000000000000000000000081565b600054610122906001600160a01b031681565b6101ba6108bf565b604051908152602001610136565b6101ba61094f565b6101ba60035481565b6101227f000000000000000000000000000000000000000000000000000000000000000081565b61010d61020e366004611494565b6109ff565b61010d610c91565b61023e610229366004611477565b60046020526000908152604090205460ff1681565b6040519015158152602001610136565b61010d61025c366004611477565b610d30565b600154610122906001600160a01b031681565b6001546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa1580156102bd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102e191906114c0565b9050801561053e576040516370a0823160e01b81523060048201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015610350573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061037491906114c0565b60405163140e25ad60e31b8152600481018490529091507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063a0712d68906024016020604051808303816000875af11580156103de573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061040291906114c0565b506040516370a0823160e01b815230600482015281907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015610469573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061048d91906114c0565b61049791906114ef565b600360008282546104a89190611506565b925050819055507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663a694fc3a826003546104ec91906114ef565b6040518263ffffffff1660e01b815260040161050a91815260200190565b600060405180830381600087803b15801561052457600080fd5b505af1158015610538573d6000803e3d6000fd5b50505050505b50565b6002546001600160a01b031633146105745760405162461bcd60e51b815260040161056b9061151e565b60405180910390fd5b6001600160a01b03919091166000908152600460205260409020805460ff1916911515919091179055565b6000546001600160a01b0316156105ee5760405162461bcd60e51b815260206004820152601360248201527210531491505116481253925512505312569151606a1b604482015260640161056b565b60008054336001600160a01b0319918216179091556001805482166001600160a01b0385811691821790925560028054909316918416918217909255604051632c3e6f0f60e11b81526004810191909152635c19a95c90829063587cde1e90602401602060405180830381865afa15801561066d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106919190611548565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401600060405180830381600087803b1580156106d257600080fd5b505af11580156106e6573d6000803e3d6000fd5b505060405163095ea7b360e01b81526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000008116600483015260001960248301528516925063095ea7b39150604401600060405180830381600087803b15801561075557600080fd5b505af1158015610769573d6000803e3d6000fd5b5050604051631e756d0f60e01b81523060048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169250631e756d0f915060240161050a565b6002546001600160a01b031633146107e35760405162461bcd60e51b815260040161056b9061151e565b6001546040516317066a5760e21b81526001600160a01b03838116600483015290911690635c19a95c90602401600060405180830381600087803b15801561082a57600080fd5b505af115801561083e573d6000803e3d6000fd5b5050604051631e756d0f60e01b81523060048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169250631e756d0f91506024015b600060405180830381600087803b1580156108a457600080fd5b505af11580156108b8573d6000803e3d6000fd5b5050505050565b60405163402914f560e01b81523060048201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063402914f590602401602060405180830381865afa158015610926573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061094a91906114c0565b905090565b6001546040516370a0823160e01b815230600482015260009182916001600160a01b03909116906370a0823190602401602060405180830381865afa15801561099c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109c091906114c0565b90506000670de0b6b3a76400006109d5610dfe565b6003546109e29190611565565b6109ec9190611584565b90506109f88183611506565b9250505090565b6000546001600160a01b03163314610a475760405162461bcd60e51b815260206004820152600b60248201526a13d393164813505492d15560aa1b604482015260640161056b565b6001546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa158015610a90573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ab491906114c0565b905081811015610c14576000610aca82846114ef565b90506000610ad6610dfe565b610ae883670de0b6b3a7640000611565565b610af29190611584565b90508060036000828254610b0691906114ef565b90915550506040516305c2fbcf60e31b8152600481018290527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690632e17de7890602401600060405180830381600087803b158015610b6d57600080fd5b505af1158015610b81573d6000803e3d6000fd5b505060405163852a12e360e01b8152600481018590527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316925063852a12e391506024016020604051808303816000875af1158015610bec573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c1091906114c0565b5050505b60015460405163a9059cbb60e01b81526001600160a01b038581166004830152602482018590529091169063a9059cbb906044016020604051808303816000875af1158015610c67573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c8b91906115a6565b50505050565b6002546001600160a01b03163314610cbb5760405162461bcd60e51b815260040161056b9061151e565b604051630f41a04d60e11b81523360048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690631e83409a90602401600060405180830381600087803b158015610d1c57600080fd5b505af1158015610c8b573d6000803e3d6000fd5b6002546001600160a01b0316331480610d5857503360009081526004602052604090205460ff165b610db05760405162461bcd60e51b8152602060048201526024808201527f4f4e4c592042454e4546494349415259204f5220414c4c4f57454420434c41496044820152634d45525360e01b606482015260840161056b565b604051630f41a04d60e11b81526001600160a01b0382811660048301527f00000000000000000000000000000000000000000000000000000000000000001690631e83409a9060240161088a565b6000807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316636c540baf6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610e5f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e8391906114c0565b9050438103610f14577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663182df0f56040518163ffffffff1660e01b8152600401602060405180830381865afa158015610eea573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f0e91906114c0565b91505090565b6000610f2082436114ef565b90506000817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316638ae39cac6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610f83573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fa791906114c0565b610fb19190611565565b90506000600160009054906101000a90046001600160a01b03166001600160a01b03166370a082317f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663c7c934a16040518163ffffffff1660e01b8152600401602060405180830381865afa158015611037573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061105b9190611548565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401602060405180830381865afa15801561109f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110c391906114c0565b90506000600160009054906101000a90046001600160a01b03166001600160a01b031663dd62ed3e7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663c7c934a16040518163ffffffff1660e01b8152600401602060405180830381865afa158015611149573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061116d9190611548565b60405160e083901b6001600160e01b03191681526001600160a01b0391821660048201527f00000000000000000000000000000000000000000000000000000000000000009091166024820152604401602060405180830381865afa1580156111da573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111fe91906114c0565b9050828211158061120f5750828111155b156112a0577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663182df0f56040518163ffffffff1660e01b8152600401602060405180830381865afa158015611272573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061129691906114c0565b9550505050505090565b6112967f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611301573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061132591906114c0565b847f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316633b1d21a26040518163ffffffff1660e01b8152600401602060405180830381865afa158015611384573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113a891906114c0565b6113b29190611506565b9060006113c883670de0b6b3a7640000846113cf565b9392505050565b60008260001904841183021582026113e657600080fd5b5091020490565b6001600160a01b038116811461053e57600080fd5b801515811461053e57600080fd5b6000806040838503121561142357600080fd5b823561142e816113ed565b9150602083013561143e81611402565b809150509250929050565b6000806040838503121561145c57600080fd5b8235611467816113ed565b9150602083013561143e816113ed565b60006020828403121561148957600080fd5b81356113c8816113ed565b600080604083850312156114a757600080fd5b82356114b2816113ed565b946020939093013593505050565b6000602082840312156114d257600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b600082821015611501576115016114d9565b500390565b60008219821115611519576115196114d9565b500190565b60208082526010908201526f4f4e4c592042454e454649434941525960801b604082015260600190565b60006020828403121561155a57600080fd5b81516113c8816113ed565b600081600019048311821515161561157f5761157f6114d9565b500290565b6000826115a157634e487b7160e01b600052601260045260246000fd5b500490565b6000602082840312156115b857600080fd5b81516113c88161140256fea2646970667358221220273827ed0840ee4dab603b05cd6aa00bd8974e8055e08ee049ac0d0ca561746264736f6c634300080d00330000000000000000000000001637e4e9941d55703a7a5e7807d6ada3f7dcd61b000000000000000000000000dcd2d918511ba39f2872eb731bb88681ae184244","name":"INVEscrow","is_blueprint":false,"license_type":"none","is_fully_verified":true,"is_verified_via_eth_bytecode_db":true,"language":"solidity","evm_version":"london","can_be_visualized_via_sol2uml":true,"is_verified_via_sourcify":true,"additional_sources":[{"file_path":"lib/solmate/src/utils/FixedPointMathLib.sol","source_code":"// SPDX-License-Identifier: AGPL-3.0-only\npragma solidity >=0.8.0;\n\n/// @notice Arithmetic library with operations for fixed-point numbers.\n/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/FixedPointMathLib.sol)\n/// @author Inspired by USM (https://github.com/usmfum/USM/blob/master/contracts/WadMath.sol)\nlibrary FixedPointMathLib {\n    /*//////////////////////////////////////////////////////////////\n                    SIMPLIFIED FIXED POINT OPERATIONS\n    //////////////////////////////////////////////////////////////*/\n\n    uint256 internal constant MAX_UINT256 = 2**256 - 1;\n\n    uint256 internal constant WAD = 1e18; // The scalar of ETH and most ERC20s.\n\n    function mulWadDown(uint256 x, uint256 y) internal pure returns (uint256) {\n        return mulDivDown(x, y, WAD); // Equivalent to (x * y) / WAD rounded down.\n    }\n\n    function mulWadUp(uint256 x, uint256 y) internal pure returns (uint256) {\n        return mulDivUp(x, y, WAD); // Equivalent to (x * y) / WAD rounded up.\n    }\n\n    function divWadDown(uint256 x, uint256 y) internal pure returns (uint256) {\n        return mulDivDown(x, WAD, y); // Equivalent to (x * WAD) / y rounded down.\n    }\n\n    function divWadUp(uint256 x, uint256 y) internal pure returns (uint256) {\n        return mulDivUp(x, WAD, y); // Equivalent to (x * WAD) / y rounded up.\n    }\n\n    /*//////////////////////////////////////////////////////////////\n                    LOW LEVEL FIXED POINT OPERATIONS\n    //////////////////////////////////////////////////////////////*/\n\n    function mulDivDown(\n        uint256 x,\n        uint256 y,\n        uint256 denominator\n    ) internal pure returns (uint256 z) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Equivalent to require(denominator != 0 && (y == 0 || x <= type(uint256).max / y))\n            if iszero(mul(denominator, iszero(mul(y, gt(x, div(MAX_UINT256, y)))))) {\n                revert(0, 0)\n            }\n\n            // Divide x * y by the denominator.\n            z := div(mul(x, y), denominator)\n        }\n    }\n\n    function mulDivUp(\n        uint256 x,\n        uint256 y,\n        uint256 denominator\n    ) internal pure returns (uint256 z) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Equivalent to require(denominator != 0 && (y == 0 || x <= type(uint256).max / y))\n            if iszero(mul(denominator, iszero(mul(y, gt(x, div(MAX_UINT256, y)))))) {\n                revert(0, 0)\n            }\n\n            // If x * y modulo the denominator is strictly greater than 0,\n            // 1 is added to round up the division of x * y by the denominator.\n            z := add(gt(mod(mul(x, y), denominator), 0), div(mul(x, y), denominator))\n        }\n    }\n\n    function rpow(\n        uint256 x,\n        uint256 n,\n        uint256 scalar\n    ) internal pure returns (uint256 z) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            switch x\n            case 0 {\n                switch n\n                case 0 {\n                    // 0 ** 0 = 1\n                    z := scalar\n                }\n                default {\n                    // 0 ** n = 0\n                    z := 0\n                }\n            }\n            default {\n                switch mod(n, 2)\n                case 0 {\n                    // If n is even, store scalar in z for now.\n                    z := scalar\n                }\n                default {\n                    // If n is odd, store x in z for now.\n                    z := x\n                }\n\n                // Shifting right by 1 is like dividing by 2.\n                let half := shr(1, scalar)\n\n                for {\n                    // Shift n right by 1 before looping to halve it.\n                    n := shr(1, n)\n                } n {\n                    // Shift n right by 1 each iteration to halve it.\n                    n := shr(1, n)\n                } {\n                    // Revert immediately if x ** 2 would overflow.\n                    // Equivalent to iszero(eq(div(xx, x), x)) here.\n                    if shr(128, x) {\n                        revert(0, 0)\n                    }\n\n                    // Store x squared.\n                    let xx := mul(x, x)\n\n                    // Round to the nearest number.\n                    let xxRound := add(xx, half)\n\n                    // Revert if xx + half overflowed.\n                    if lt(xxRound, xx) {\n                        revert(0, 0)\n                    }\n\n                    // Set x to scaled xxRound.\n                    x := div(xxRound, scalar)\n\n                    // If n is even:\n                    if mod(n, 2) {\n                        // Compute z * x.\n                        let zx := mul(z, x)\n\n                        // If z * x overflowed:\n                        if iszero(eq(div(zx, x), z)) {\n                            // Revert if x is non-zero.\n                            if iszero(iszero(x)) {\n                                revert(0, 0)\n                            }\n                        }\n\n                        // Round to the nearest number.\n                        let zxRound := add(zx, half)\n\n                        // Revert if zx + half overflowed.\n                        if lt(zxRound, zx) {\n                            revert(0, 0)\n                        }\n\n                        // Return properly scaled zxRound.\n                        z := div(zxRound, scalar)\n                    }\n                }\n            }\n        }\n    }\n\n    /*//////////////////////////////////////////////////////////////\n                        GENERAL NUMBER UTILITIES\n    //////////////////////////////////////////////////////////////*/\n\n    function sqrt(uint256 x) internal pure returns (uint256 z) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            let y := x // We start y at x, which will help us make our initial estimate.\n\n            z := 181 // The \"correct\" value is 1, but this saves a multiplication later.\n\n            // This segment is to get a reasonable initial estimate for the Babylonian method. With a bad\n            // start, the correct # of bits increases ~linearly each iteration instead of ~quadratically.\n\n            // We check y >= 2^(k + 8) but shift right by k bits\n            // each branch to ensure that if x >= 256, then y >= 256.\n            if iszero(lt(y, 0x10000000000000000000000000000000000)) {\n                y := shr(128, y)\n                z := shl(64, z)\n            }\n            if iszero(lt(y, 0x1000000000000000000)) {\n                y := shr(64, y)\n                z := shl(32, z)\n            }\n            if iszero(lt(y, 0x10000000000)) {\n                y := shr(32, y)\n                z := shl(16, z)\n            }\n            if iszero(lt(y, 0x1000000)) {\n                y := shr(16, y)\n                z := shl(8, z)\n            }\n\n            // Goal was to get z*z*y within a small factor of x. More iterations could\n            // get y in a tighter range. Currently, we will have y in [256, 256*2^16).\n            // We ensured y >= 256 so that the relative difference between y and y+1 is small.\n            // That's not possible if x < 256 but we can just verify those cases exhaustively.\n\n            // Now, z*z*y <= x < z*z*(y+1), and y <= 2^(16+8), and either y >= 256, or x < 256.\n            // Correctness can be checked exhaustively for x < 256, so we assume y >= 256.\n            // Then z*sqrt(y) is within sqrt(257)/sqrt(256) of sqrt(x), or about 20bps.\n\n            // For s in the range [1/256, 256], the estimate f(s) = (181/1024) * (s+1) is in the range\n            // (1/2.84 * sqrt(s), 2.84 * sqrt(s)), with largest error when s = 1 and when s = 256 or 1/256.\n\n            // Since y is in [256, 256*2^16), let a = y/65536, so that a is in [1/256, 256). Then we can estimate\n            // sqrt(y) using sqrt(65536) * 181/1024 * (a + 1) = 181/4 * (y + 65536)/65536 = 181 * (y + 65536)/2^18.\n\n            // There is no overflow risk here since y < 2^136 after the first branch above.\n            z := shr(18, mul(z, add(y, 65536))) // A mul() is saved from starting z at 181.\n\n            // Given the worst case multiplicative error of 2.84 above, 7 iterations should be enough.\n            z := shr(1, add(z, div(x, z)))\n            z := shr(1, add(z, div(x, z)))\n            z := shr(1, add(z, div(x, z)))\n            z := shr(1, add(z, div(x, z)))\n            z := shr(1, add(z, div(x, z)))\n            z := shr(1, add(z, div(x, z)))\n            z := shr(1, add(z, div(x, z)))\n\n            // If x+1 is a perfect square, the Babylonian method cycles between\n            // floor(sqrt(x)) and ceil(sqrt(x)). This statement ensures we return floor.\n            // See: https://en.wikipedia.org/wiki/Integer_square_root#Using_only_integer_division\n            // Since the ceil is rare, we save gas on the assignment and repeat division in the rare case.\n            // If you don't care whether the floor or ceil square root is returned, you can remove this statement.\n            z := sub(z, lt(div(x, z), z))\n        }\n    }\n\n    function unsafeMod(uint256 x, uint256 y) internal pure returns (uint256 z) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Mod x by y. Note this will return\n            // 0 instead of reverting if y is zero.\n            z := mod(x, y)\n        }\n    }\n\n    function unsafeDiv(uint256 x, uint256 y) internal pure returns (uint256 r) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Divide x by y. Note this will return\n            // 0 instead of reverting if y is zero.\n            r := div(x, y)\n        }\n    }\n\n    function unsafeDivUp(uint256 x, uint256 y) internal pure returns (uint256 z) {\n        /// @solidity memory-safe-assembly\n        assembly {\n            // Add 1 to x * y if x % y > 0. Note this will\n            // return 0 instead of reverting if y is zero.\n            z := add(gt(mod(x, y), 0), div(x, y))\n        }\n    }\n}\n"},{"file_path":"src/interfaces/IERC20.sol","source_code":"pragma solidity ^0.8.13;\n\ninterface IERC20 {\n    function approve(address,uint) external;\n    function transfer(address,uint) external returns (bool);\n    function transferFrom(address,address,uint) external returns (bool);\n    function balanceOf(address) external view returns (uint);\n    function allowance(address from, address to) external view returns (uint);\n}\n\ninterface IDelegateableERC20 is IERC20 {\n    function delegate(address delegatee) external;\n    function delegates(address delegator) external view returns (address delegatee);\n}\n\n"}],"certified":false,"conflicting_implementations":null,"abi":[{"inputs":[{"internalType":"contract IXINV","name":"_xINV","type":"address"},{"internalType":"contract IDbrDistributor","name":"_distributor","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"balance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"beneficiary","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"claimDBR","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"claimDBRTo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"claimable","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"claimers","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"delegatee","type":"address"}],"name":"delegate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"distributor","outputs":[{"internalType":"contract IDbrDistributor","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IDelegateableERC20","name":"_token","type":"address"},{"internalType":"address","name":"_beneficiary","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"market","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"onDeposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"pay","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"claimer","type":"address"},{"internalType":"bool","name":"allowed","type":"bool"}],"name":"setClaimer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"stakedXINV","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"token","outputs":[{"internalType":"contract IDelegateableERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"xINV","outputs":[{"internalType":"contract IXINV","name":"","type":"address"}],"stateMutability":"view","type":"function"}],"is_changed_bytecode":false,"is_partially_verified":false,"constructor_args":"0000000000000000000000001637e4e9941d55703a7a5e7807d6ada3f7dcd61b000000000000000000000000dcd2d918511ba39f2872eb731bb88681ae184244"}