UNPKG

@fleupold/dex-contracts

Version:

Contracts for dFusion multi-token batch auction exchange

331 lines 849 kB
{ "contractName": "EpochTokenLocker", "abi": [ { "constant": true, "inputs": [ { "name": "", "type": "address" }, { "name": "", "type": "address" } ], "name": "lastCreditBatchId", "outputs": [ { "name": "", "type": "uint32" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "BATCH_TIME", "outputs": [ { "name": "", "type": "uint32" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "user", "type": "address" }, { "indexed": true, "name": "token", "type": "address" }, { "indexed": false, "name": "amount", "type": "uint256" }, { "indexed": false, "name": "batchId", "type": "uint32" } ], "name": "Deposit", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "user", "type": "address" }, { "indexed": true, "name": "token", "type": "address" }, { "indexed": false, "name": "amount", "type": "uint256" }, { "indexed": false, "name": "batchId", "type": "uint32" } ], "name": "WithdrawRequest", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "user", "type": "address" }, { "indexed": true, "name": "token", "type": "address" }, { "indexed": false, "name": "amount", "type": "uint256" } ], "name": "Withdraw", "type": "event" }, { "constant": false, "inputs": [ { "name": "token", "type": "address" }, { "name": "amount", "type": "uint256" } ], "name": "deposit", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "token", "type": "address" }, { "name": "amount", "type": "uint256" } ], "name": "requestWithdraw", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "token", "type": "address" }, { "name": "amount", "type": "uint256" }, { "name": "batchId", "type": "uint32" } ], "name": "requestFutureWithdraw", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "user", "type": "address" }, { "name": "token", "type": "address" } ], "name": "withdraw", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": true, "inputs": [ { "name": "user", "type": "address" }, { "name": "token", "type": "address" } ], "name": "getPendingDeposit", "outputs": [ { "name": "", "type": "uint256" }, { "name": "", "type": "uint32" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "user", "type": "address" }, { "name": "token", "type": "address" } ], "name": "getPendingWithdraw", "outputs": [ { "name": "", "type": "uint256" }, { "name": "", "type": "uint32" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "getCurrentBatchId", "outputs": [ { "name": "", "type": "uint32" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "getSecondsRemainingInBatch", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "user", "type": "address" }, { "name": "token", "type": "address" } ], "name": "getBalance", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "user", "type": "address" }, { "name": "token", "type": "address" } ], "name": "hasValidWithdrawRequest", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" } ], "metadata": "{\"compiler\":{\"version\":\"0.5.10+commit.5a6ea5b1\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"constant\":true,\"inputs\":[],\"name\":\"getSecondsRemainingInBatch\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"token\",\"type\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"requestWithdraw\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"token\",\"type\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"deposit\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"address\"},{\"name\":\"\",\"type\":\"address\"}],\"name\":\"lastCreditBatchId\",\"outputs\":[{\"name\":\"\",\"type\":\"uint32\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"user\",\"type\":\"address\"},{\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getPendingDeposit\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"},{\"name\":\"\",\"type\":\"uint32\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"user\",\"type\":\"address\"},{\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getPendingWithdraw\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"},{\"name\":\"\",\"type\":\"uint32\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"user\",\"type\":\"address\"},{\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getBalance\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"BATCH_TIME\",\"outputs\":[{\"name\":\"\",\"type\":\"uint32\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"getCurrentBatchId\",\"outputs\":[{\"name\":\"\",\"type\":\"uint32\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"token\",\"type\":\"address\"},{\"name\":\"amount\",\"type\":\"uint256\"},{\"name\":\"batchId\",\"type\":\"uint32\"}],\"name\":\"requestFutureWithdraw\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"user\",\"type\":\"address\"},{\"name\":\"token\",\"type\":\"address\"}],\"name\":\"hasValidWithdrawRequest\",\"outputs\":[{\"name\":\"\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"user\",\"type\":\"address\"},{\"name\":\"token\",\"type\":\"address\"}],\"name\":\"withdraw\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"user\",\"type\":\"address\"},{\"indexed\":true,\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"batchId\",\"type\":\"uint32\"}],\"name\":\"Deposit\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"user\",\"type\":\"address\"},{\"indexed\":true,\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"batchId\",\"type\":\"uint32\"}],\"name\":\"WithdrawRequest\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"user\",\"type\":\"address\"},{\"indexed\":true,\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Withdraw\",\"type\":\"event\"}],\"devdoc\":{\"author\":\"@gnosis/dfusion-team <https://github.com/orgs/gnosis/teams/dfusion-team/members>\",\"methods\":{\"deposit(address,uint256)\":{\"details\":\"credits user with deposit amount on next epoch (given by getCurrentBatchId)\",\"params\":{\"amount\":\"number of token(s) to be credited to user's account * Emits an {Deposit} event with relevent deposit information. * Requirements: - token transfer to contract is successfull\",\"token\":\"address of token to be deposited\"}},\"getBalance(address,address)\":{\"details\":\"fetches and returns user's balance\",\"params\":{\"token\":\"address of ERC20 token return Current `token` balance of `user`'s account\",\"user\":\"address of user\"}},\"getCurrentBatchId()\":{\"details\":\"getter function to determine current auction id. return current batchId\"},\"getPendingDeposit(address,address)\":{\"details\":\"getter function used to display pending deposit\",\"params\":{\"token\":\"address of ERC20 token return amount and batchId of deposit's transfer if any (else 0)\",\"user\":\"address of user\"}},\"getPendingWithdraw(address,address)\":{\"details\":\"getter function used to display pending withdraw\",\"params\":{\"token\":\"address of ERC20 token return amount and batchId when withdraw was requested if any (else 0)\",\"user\":\"address of user\"}},\"getSecondsRemainingInBatch()\":{\"details\":\"used to determine how much time is left in a batch return seconds remaining in current batch\"},\"hasValidWithdrawRequest(address,address)\":{\"details\":\"Used to determine if user has a valid pending withdraw request of specific token\",\"params\":{\"token\":\"address of ERC20 token return true if `user` has valid withdraw request for `token`, otherwise false\",\"user\":\"address of user\"}},\"requestFutureWithdraw(address,uint256,uint32)\":{\"details\":\"Signals and initiates user's intent to withdraw.\",\"params\":{\"amount\":\"number of token(s) to be withdrawn\",\"batchId\":\"state index at which request is to be made. * Emits an {WithdrawRequest} event with relevent request information.\",\"token\":\"address of token to be withdrawn\"}},\"requestWithdraw(address,uint256)\":{\"details\":\"Signals and initiates user's intent to withdraw.\",\"params\":{\"amount\":\"number of token(s) to be withdrawn * Emits an {WithdrawRequest} event with relevent request information.\",\"token\":\"address of token to be withdrawn\"}},\"withdraw(address,address)\":{\"details\":\"Claims pending withdraw - can be called on behalf of others\",\"params\":{\"token\":\"address of token to be withdrawn\",\"user\":\"address of user who withdraw is being claimed. * Emits an {Withdraw} event stating that `user` withdrew `amount` of `token` * Requirements: - withdraw was requested in previous epoch - token was received from exchange in current auction batch\"}}},\"title\":\"Epoch Token Locker EpochTokenLocker saveguards tokens for applications with constant-balances during discrete epochs It allows to deposit a token which become credited in the next epoch and allows to request a token-withdraw which becomes claimable after the current epoch has expired.\"},\"userdoc\":{\"methods\":{}}},\"settings\":{\"compilationTarget\":{\"/Users/felixleupold/Gnosis/dex-contracts/contracts/EpochTokenLocker.sol\":\"EpochTokenLocker\"},\"evmVersion\":\"petersburg\",\"libraries\":{},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"/Users/felixleupold/Gnosis/dex-contracts/contracts/EpochTokenLocker.sol\":{\"keccak256\":\"0x6a0e16a44b858c3af0e4e0113af93bf23160f175f36c524f9e753085d8de9978\",\"urls\":[\"bzzr://d6178f1d3533ed733e7eba91d12ce1597711e5b74ad1a4492aed9dc28a8d5c97\",\"dweb:/ipfs/QmeVeD8xeZUfwRi4BCBhrBWCHUDF3tdzwwYDgSNr5T4xPo\"]},\"@openzeppelin/contracts/math/Math.sol\":{\"keccak256\":\"0x4b5aa451e4e8801478708f94b118a7821c0500d676255eaf89fc78c14856ce4e\",\"urls\":[\"bzzr://200d5728b32858918810d8d7a8db1406ee9b157ad5026f050e6d864a696b9080\",\"dweb:/ipfs/QmS6tW81u8E4tvzVfVuqEuMCkdwAozQ6pKJPRBR4JEVmQp\"]},\"@openzeppelin/contracts/math/SafeMath.sol\":{\"keccak256\":\"0x640b6dee7a4b830bdfd52b5031a07fc2b12209f5b2e29e5d364a7d37f69d8076\",\"urls\":[\"bzzr://292843005e754e752644f767477ec5ad7a1ffc91ddb18c38b8079c62f3993cad\",\"dweb:/ipfs/QmbZaJyXdpsYGykVhHH9qpVGQg9DGCxE2QufbCUy3daTgq\"]},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"keccak256\":\"0xe5bb0f57cff3e299f360052ba50f1ea0fff046df2be070b6943e0e3c3fdad8a9\",\"urls\":[\"bzzr://cf2d583b8dce38d0617fdcd65f2fd9f126fe17b7f683b5a515ea9d2762d8b062\",\"dweb:/ipfs/QmQMvwEcPhoRXzbXyrdoeRtvLoifUW9Qh7Luho7bmUPRkc\"]},\"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\":{\"keccak256\":\"0x6f2c9955d65c522b80f4b8792f076512d2df947d2112cbc4d98a4781ed42ede2\",\"urls\":[\"bzzr://d2ff5aadcb697bc27ca3b0f6c40b4998e8cf0a1bd0f761d1df6d5981777841ae\",\"dweb:/ipfs/QmTDkFzKnrpiV1UKnSoiZAHPuguWzokrr4pFbSPvyaSo56\"]},\"@openzeppelin/contracts/utils/Address.sol\":{\"keccak256\":\"0x1a8e5072509c5ea7365eb1d48030b9be865140c8fb779968da0a459a0e174a11\",\"urls\":[\"bzzr://4e1d23731da27602b8c552e54fb9976dadf8cf46a8f90a3c8c1b85fe044618b9\",\"dweb:/ipfs/Qmebp4nzPja645c9yXSdJkGq96oU3am3LUnG2K3R7XxyKf\"]}},\"version\":1}", "bytecode": "0x608060405234801561001057600080fd5b50610f2c806100206000396000f3fe608060405234801561001057600080fd5b50600436106100b45760003560e01c8063d4fac45d11610071578063d4fac45d146101ee578063e48c015e1461021c578063e720ac8e14610224578063f36b63551461022c578063f3f4798214610264578063f940e385146102a6576100b4565b806317569c1d146100b9578063397a1b28146100d357806347e7ef2414610101578063907767c01461012d578063b3c0afa114610174578063c33eb9f6146101c0575b600080fd5b6100c16102d4565b60408051918252519081900360200190f35b6100ff600480360360408110156100e957600080fd5b506001600160a01b0381351690602001356102e0565b005b6100ff6004803603604081101561011757600080fd5b506001600160a01b0381351690602001356102f6565b61015b6004803603604081101561014357600080fd5b506001600160a01b03813581169160200135166103f7565b6040805163ffffffff9092168252519081900360200190f35b6101a26004803603604081101561018a57600080fd5b506001600160a01b038135811691602001351661041a565b6040805192835263ffffffff90911660208301528051918290030190f35b6101a2600480360360408110156101d657600080fd5b506001600160a01b0381358116916020013516610474565b6100c16004803603604081101561020457600080fd5b506001600160a01b03813581169160200135166104ce565b61015b6105f9565b61015b6105ff565b6100ff6004803603606081101561024257600080fd5b5080356001600160a01b0316906020810135906040013563ffffffff16610607565b6102926004803603604081101561027a57600080fd5b506001600160a01b038135811691602001351661070e565b604080519115158252519081900360200190f35b6100ff600480360360408110156102bc57600080fd5b506001600160a01b0381358116916020013516610786565b61012c42819006900390565b6102f282826102ed6105ff565b610607565b5050565b610300338361097d565b61030c82333084610a3e565b336000908152602081815260408083206001600160a01b0386168452909152902060010154610341908263ffffffff610a9e16565b336000908152602081815260408083206001600160a01b038716845290915290206001015561036e6105ff565b336000818152602081815260408083206001600160a01b0388168085529252909120600201805463ffffffff191663ffffffff94909416939093179092557fc11cc34e93c67a93382b99f2498e9937198798f3c1c2888008ffc0eeb82f68c4836103d66105ff565b6040805192835263ffffffff90911660208301528051918290030190a35050565b600160209081526000928352604080842090915290825290205463ffffffff1681565b600080610425610e29565b5050506001600160a01b039182166000908152602081815260408083209390941682529182528290208251808401909352600181015480845260029091015463ffffffff169290910182905291565b60008061047f610e29565b5050506001600160a01b039182166000908152602081815260408083209390941682529182528290208251808401909352600381015480845260049091015463ffffffff169290910182905291565b6001600160a01b038083166000908152602081815260408083209385168352929052908120546104fc6105ff565b6001600160a01b038086166000908152602081815260408083209388168352929052206002015463ffffffff9182169116101561056e576001600160a01b038085166000908152602081815260408083209387168352929052206001015461056b90829063ffffffff610a9e16565b90505b6105766105ff565b6001600160a01b038086166000908152602081815260408083209388168352929052206004015463ffffffff918216911610156105f2576001600160a01b03808516600090815260208181526040808320938716835292905220600301546105ef906105e29083610af8565b829063ffffffff610b0e16565b90505b9392505050565b61012c81565b61012c420490565b610611338461070e565b15610620576106203384610786565b6106286105ff565b63ffffffff168163ffffffff1610156106725760405162461bcd60e51b8152600401808060200182810382526022815260200180610ed66022913960400191505060405180910390fd5b60408051808201825283815263ffffffff83811660208084018281523360008181528084528781206001600160a01b038c16808352908552908890209651600388015591516004909601805463ffffffff19169690951695909517909355845187815290810191909152835191937f2c6245af506f0fc1089918c02c1d01bde9cc807609b334b3e7644d6dfb5a6c5e92918290030190a3505050565b60006107186105ff565b6001600160a01b038085166000908152602081815260408083209387168352929052206004015463ffffffff91821691161080156105f25750506001600160a01b0391821660009081526020818152604080832093909416825291909152206004015463ffffffff16151590565b610790828261097d565b6107986105ff565b6001600160a01b038084166000908152602081815260408083209386168352929052206004015463ffffffff9182169116106108055760405162461bcd60e51b8152600401808060200182810382526026815260200180610e866026913960400191505060405180910390fd5b61080d6105ff565b6001600160a01b0380841660009081526001602090815260408083209386168352929052205463ffffffff9182169116106108795760405162461bcd60e51b8152600401808060200182810382526045815260200180610e416045913960600191505060405180910390fd5b6001600160a01b03828116600090815260208181526040808320938516835292905290812080546003909101546108b09190610af8565b6001600160a01b03808516600090815260208181526040808320938716835292905220549091506108e7908263ffffffff610b0e16565b6001600160a01b0384811660009081526020818152604080832093871683529290529081209182556003820155600401805463ffffffff1916905561092d828483610b50565b816001600160a01b0316836001600160a01b03167f9b1bfa7fa9ee420a16e124f794c35ac9f90472acc99140eb2f6447c714cad8eb836040518082815260200191505060405180910390a3505050565b6001600160a01b038083166000908152602081815260408083209385168352929052206002015463ffffffff1680158015906109c557506109bc6105ff565b63ffffffff1681105b15610a39576001600160a01b03838116600090815260208181526040808320938616835292905220600181015490546109fd91610a9e565b6001600160a01b0384811660009081526020818152604080832093871683529290529081209182556001820155600201805463ffffffff191690555b505050565b604080516001600160a01b0385811660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b179052610a98908590610b9e565b50505050565b6000828201838110156105f2576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b6000818310610b0757816105f2565b5090919050565b60006105f283836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250610d56565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b179052610a399084905b610bb0826001600160a01b0316610ded565b610c01576040805162461bcd60e51b815260206004820152601f60248201527f5361666545524332303a2063616c6c20746f206e6f6e2d636f6e747261637400604482015290519081900360640190fd5b60006060836001600160a01b0316836040518082805190602001908083835b60208310610c3f5780518252601f199092019160209182019101610c20565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114610ca1576040519150601f19603f3d011682016040523d82523d6000602084013e610ca6565b606091505b509150915081610cfd576040805162461bcd60e51b815260206004820181905260248201527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564604482015290519081900360640190fd5b805115610a9857808060200190516020811015610d1957600080fd5b5051610a985760405162461bcd60e51b815260040180806020018281038252602a815260200180610eac602a913960400191505060405180910390fd5b60008184841115610de55760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015610daa578181015183820152602001610d92565b50505050905090810190601f168015610dd75780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470818114801590610e2157508115155b949350505050565b60408051808201909152600080825260208201529056fe5769746864726177206e6f7420706f737369626c6520666f7220746f6b656e20746861742069732074726164656420696e207468652063757272656e742061756374696f6e776974686472617720776173206e6f7420726567697374657265642070726576696f75736c795361666545524332303a204552433230206f7065726174696f6e20646964206e6f742073756363656564526571756573742063616e6e6f74206265206d61646520696e207468652070617374a265627a7a72305820be0fd89201be28c08e5fb7bc53b0c5240e0198ee2b2a8b3d4820f6a310fee49764736f6c634300050a0032", "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100b45760003560e01c8063d4fac45d11610071578063d4fac45d146101ee578063e48c015e1461021c578063e720ac8e14610224578063f36b63551461022c578063f3f4798214610264578063f940e385146102a6576100b4565b806317569c1d146100b9578063397a1b28146100d357806347e7ef2414610101578063907767c01461012d578063b3c0afa114610174578063c33eb9f6146101c0575b600080fd5b6100c16102d4565b60408051918252519081900360200190f35b6100ff600480360360408110156100e957600080fd5b506001600160a01b0381351690602001356102e0565b005b6100ff6004803603604081101561011757600080fd5b506001600160a01b0381351690602001356102f6565b61015b6004803603604081101561014357600080fd5b506001600160a01b03813581169160200135166103f7565b6040805163ffffffff9092168252519081900360200190f35b6101a26004803603604081101561018a57600080fd5b506001600160a01b038135811691602001351661041a565b6040805192835263ffffffff90911660208301528051918290030190f35b6101a2600480360360408110156101d657600080fd5b506001600160a01b0381358116916020013516610474565b6100c16004803603604081101561020457600080fd5b506001600160a01b03813581169160200135166104ce565b61015b6105f9565b61015b6105ff565b6100ff6004803603606081101561024257600080fd5b5080356001600160a01b0316906020810135906040013563ffffffff16610607565b6102926004803603604081101561027a57600080fd5b506001600160a01b038135811691602001351661070e565b604080519115158252519081900360200190f35b6100ff600480360360408110156102bc57600080fd5b506001600160a01b0381358116916020013516610786565b61012c42819006900390565b6102f282826102ed6105ff565b610607565b5050565b610300338361097d565b61030c82333084610a3e565b336000908152602081815260408083206001600160a01b0386168452909152902060010154610341908263ffffffff610a9e16565b336000908152602081815260408083206001600160a01b038716845290915290206001015561036e6105ff565b336000818152602081815260408083206001600160a01b0388168085529252909120600201805463ffffffff191663ffffffff94909416939093179092557fc11cc34e93c67a93382b99f2498e9937198798f3c1c2888008ffc0eeb82f68c4836103d66105ff565b6040805192835263ffffffff90911660208301528051918290030190a35050565b600160209081526000928352604080842090915290825290205463ffffffff1681565b600080610425610e29565b5050506001600160a01b039182166000908152602081815260408083209390941682529182528290208251808401909352600181015480845260029091015463ffffffff169290910182905291565b60008061047f610e29565b5050506001600160a01b039182166000908152602081815260408083209390941682529182528290208251808401909352600381015480845260049091015463ffffffff169290910182905291565b6001600160a01b038083166000908152602081815260408083209385168352929052908120546104fc6105ff565b6001600160a01b038086166000908152602081815260408083209388168352929052206002015463ffffffff9182169116101561056e576001600160a01b038085166000908152602081815260408083209387168352929052206001015461056b90829063ffffffff610a9e16565b90505b6105766105ff565b6001600160a01b038086166000908152602081815260408083209388168352929052206004015463ffffffff918216911610156105f2576001600160a01b03808516600090815260208181526040808320938716835292905220600301546105ef906105e29083610af8565b829063ffffffff610b0e16565b90505b9392505050565b61012c81565b61012c420490565b610611338461070e565b15610620576106203384610786565b6106286105ff565b63ffffffff168163ffffffff1610156106725760405162461bcd60e51b8152600401808060200182810382526022815260200180610ed66022913960400191505060405180910390fd5b60408051808201825283815263ffffffff83811660208084018281523360008181528084528781206001600160a01b038c16808352908552908890209651600388015591516004909601805463ffffffff19169690951695909517909355845187815290810191909152835191937f2c6245af506f0fc1089918c02c1d01bde9cc807609b334b3e7644d6dfb5a6c5e92918290030190a3505050565b60006107186105ff565b6001600160a01b038085166000908152602081815260408083209387168352929052206004015463ffffffff91821691161080156105f25750506001600160a01b0391821660009081526020818152604080832093909416825291909152206004015463ffffffff16151590565b610790828261097d565b6107986105ff565b6001600160a01b038084166000908152602081815260408083209386168352929052206004015463ffffffff9182169116106108055760405162461bcd60e51b8152600401808060200182810382526026815260200180610e866026913960400191505060405180910390fd5b61080d6105ff565b6001600160a01b0380841660009081526001602090815260408083209386168352929052205463ffffffff9182169116106108795760405162461bcd60e51b8152600401808060200182810382526045815260200180610e416045913960600191505060405180910390fd5b6001600160a01b03828116600090815260208181526040808320938516835292905290812080546003909101546108b09190610af8565b6001600160a01b03808516600090815260208181526040808320938716835292905220549091506108e7908263ffffffff610b0e16565b6001600160a01b0384811660009081526020818152604080832093871683529290529081209182556003820155600401805463ffffffff1916905561092d828483610b50565b816001600160a01b0316836001600160a01b03167f9b1bfa7fa9ee420a16e124f794c35ac9f90472acc99140eb2f6447c714cad8eb836040518082815260200191505060405180910390a3505050565b6001600160a01b038083166000908152602081815260408083209385168352929052206002015463ffffffff1680158015906109c557506109bc6105ff565b63ffffffff1681105b15610a39576001600160a01b03838116600090815260208181526040808320938616835292905220600181015490546109fd91610a9e565b6001600160a01b0384811660009081526020818152604080832093871683529290529081209182556001820155600201805463ffffffff191690555b505050565b604080516001600160a01b0385811660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b179052610a98908590610b9e565b50505050565b6000828201838110156105f2576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b6000818310610b0757816105f2565b5090919050565b60006105f283836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250610d56565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b179052610a399084905b610bb0826001600160a01b0316610ded565b610c01576040805162461bcd60e51b815260206004820152601f60248201527f5361666545524332303a2063616c6c20746f206e6f6e2d636f6e747261637400604482015290519081900360640190fd5b60006060836001600160a01b0316836040518082805190602001908083835b60208310610c3f5780518252601f199092019160209182019101610c20565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114610ca1576040519150601f19603f3d011682016040523d82523d6000602084013e610ca6565b606091505b509150915081610cfd576040805162461bcd60e51b815260206004820181905260248201527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564604482015290519081900360640190fd5b805115610a9857808060200190516020811015610d1957600080fd5b5051610a985760405162461bcd60e51b815260040180806020018281038252602a815260200180610eac602a913960400191505060405180910390fd5b60008184841115610de55760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015610daa578181015183820152602001610d92565b50505050905090810190601f168015610dd75780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470818114801590610e2157508115155b949350505050565b60408051808201909152600080825260208201529056fe5769746864726177206e6f7420706f737369626c6520666f7220746f6b656e20746861742069732074726164656420696e207468652063757272656e742061756374696f6e776974686472617720776173206e6f7420726567697374657265642070726576696f75736c795361666545524332303a204552433230206f7065726174696f6e20646964206e6f742073756363656564526571756573742063616e6e6f74206265206d61646520696e207468652070617374a265627a7a72305820be0fd89201be28c08e5fb7bc53b0c5240e0198ee2b2a8b3d4820f6a310fee49764736f6c634300050a0032", "sourceMap": "649:10969:3:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;649:10969:3;;;;;;;", "deployedSourceMap": "649:10969:3:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;649:10969:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6732:177;;;:::i;:::-;;;;;;;;;;;;;;;;2918:137;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;2918:137:3;;;;;;;;:::i;:::-;;2085:566;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;2085:566:3;;;;;;;;:::i;972:71::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;972:71:3;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;5597:253;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;5597:253:3;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;6081:258;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;6081:258:3;;;;;;;;;;:::i;7107:561::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;7107:561:3;;;;;;;;;;:::i;766:39::-;;;:::i;6445:160::-;;;:::i;3388:604::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;3388:604:3;;-1:-1:-1;;;;;3388:604:3;;;;;;;;;;;;;:::i;7939:269::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;7939:269:3;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;4432:896;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;4432:896:3;;;;;;;;;;:::i;6732:177::-;802:3;6885;:16;;;6871:31;;;6732:177::o;2918:137::-;2991:57;3013:5;3020:6;3028:19;:17;:19::i;:::-;2991:21;:57::i;:::-;2918:137;;:::o;2085:566::-;2150:40;2172:10;2184:5;2150:21;:40::i;:::-;2200:76;2234:5;2242:10;2262:4;2269:6;2200:26;:76::i;:::-;2411:10;2397:13;:25;;;;;;;;;;;-1:-1:-1;;;;;2397:32:3;;;;;;;;;:48;;:55;:89;;2470:6;2397:89;:59;:89;:::i;:::-;2353:10;2339:13;:25;;;;;;;;;;;-1:-1:-1;;;;;2339:32:3;;;;;;;;;:48;;:147;2555:19;:17;:19::i;:::-;2510:10;2496:13;:25;;;;;;;;;;;-1:-1:-1;;;;;2496:32:3;;;;;;;;;;:56;;:78;;-1:-1:-1;;2496:78:3;;;;;;;;;;;;;2589:55;2616:6;2624:19;:17;:19::i;:::-;2589:55;;;;;;;;;;;;;;;;;;;;;;;2085:566;;:::o;972:71::-;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;5597:253::-;5674:7;5683:6;5701:33;;:::i;:::-;-1:-1:-1;;;;;;;;5737:19:3;;;:13;:19;;;;;;;;;;;:26;;;;;;;;;;;;5701:78;;;;;;;;5737:42;;;5701:78;;;;;;;;;;;;;;;;;;;5597:253::o;6081:258::-;6159:7;6168:6;6186:34;;:::i;:::-;-1:-1:-1;;;;;;;;6223:19:3;;;:13;:19;;;;;;;;;;;:26;;;;;;;;;;;;6186:80;;;;;;;;6223:43;;;6186:80;;;;;;;;;;;;;;;;;;;6081:258::o;7107:561::-;-1:-1:-1;;;;;7214:19:3;;;7177:7;7214:19;;;;;;;;;;;:26;;;;;;;;;;;:34;7315:19;:17;:19::i;:::-;-1:-1:-1;;;;;7262:19:3;;;:13;:19;;;;;;;;;;;:26;;;;;;;;;:50;;;:72;;;;:50;;:72;7258:175;;;-1:-1:-1;;;;;7372:19:3;;;:13;:19;;;;;;;;;;;:26;;;;;;;;;:42;;:49;7360:62;;:7;;:62;:11;:62;:::i;:::-;7350:72;;7258:175;7500:19;:17;:19::i;:::-;-1:-1:-1;;;;;7446:19:3;;;:13;:19;;;;;;;;;;;:26;;;;;;;;;:51;;;:73;;;;:51;;:73;7442:196;;;-1:-1:-1;;;;;7566:19:3;;;:13;:19;;;;;;;;;;;:26;;;;;;;;;:43;;:50;7545:82;;7557:69;;7618:7;7557:8;:69::i;:::-;7545:7;;:82;:11;:82;:::i;:::-;7535:92;;7442:196;7654:7;7107:561;-1:-1:-1;;;7107:561:3:o;766:39::-;802:3;766:39;:::o;6445:160::-;802:3;6581;:16;;6445:160::o;3388:604::-;3628:42;3652:10;3664:5;3628:23;:42::i;:::-;3624:100;;;3686:27;3695:10;3707:5;3686:8;:27::i;:::-;3752:19;:17;:19::i;:::-;3741:30;;:7;:30;;;;3733:77;;;;-1:-1:-1;;;3733:77:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3872:47;;;;;;;;;;;;;;;;;;;;;;3834:10;-1:-1:-1;3820:25:3;;;;;;;;;-1:-1:-1;;;;;3820:32:3;;;;;;;;;;;;:99;;:49;;;:99;;;;;;;;;-1:-1:-1;;3820:99:3;;;;;;;;;;;;3934:51;;;;;;;;;;;;;;3820:32;;3934:51;;;;;;;;;3388:604;;;:::o;7939:269::-;8022:4;8111:19;:17;:19::i;:::-;-1:-1:-1;;;;;8057:19:3;;;:13;:19;;;;;;;;;;;:26;;;;;;;;;:51;;;:73;;;;:51;;:73;:144;;;;-1:-1:-1;;;;;;;8146:19:3;;;8200:1;8146:19;;;;;;;;;;;:26;;;;;;;;;;;:51;;;;;:55;;;7939:269::o;4432:896::-;4496:34;4518:4;4524:5;4496:21;:34::i;:::-;4677:19;:17;:19::i;:::-;-1:-1:-1;;;;;4623:19:3;;;:13;:19;;;;;;;;;;;:26;;;;;;;;;:51;;;:73;;;;:51;;:73;4602:158;;;;-1:-1:-1;;;4602:158:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4824:19;:17;:19::i;:::-;-1:-1:-1;;;;;4791:23:3;;;;;;;:17;:23;;;;;;;;:30;;;;;;;;;;:52;;;;:30;;:52;4770:168;;;;-1:-1:-1;;;4770:168:3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;4974:19:3;;;4948:14;4974:19;;;;;;;;;;;:26;;;;;;;;;;;:34;;5010:43;;;;:50;4965:96;;4974:34;4965:8;:96::i;:::-;-1:-1:-1;;;;;5109:19:3;;;:13;:19;;;;;;;;;;;:26;;;;;;;;;:34;4948:113;;-1:-1:-1;5109:46:3;;4948:113;5109:46;:38;:46;:::i;:::-;-1:-1:-1;;;;;5072:19:3;;;:13;:19;;;;;;;;;;;:26;;;;;;;;;;;:83;;;5172:43;;;5165:50;;;;;-1:-1:-1;;5165:50:3;;;5226:51;5072:26;:19;5270:6;5226:22;:51::i;:::-;5307:5;-1:-1:-1;;;;;5292:29:3;5301:4;-1:-1:-1;;;;;5292:29:3;;5314:6;5292:29;;;;;;;;;;;;;;;;;;4432:896;;;:::o;11062:554::-;-1:-1:-1;;;;;11158:19:3;;;11140:15;11158:19;;;;;;;;;;;:26;;;;;;;;;:50;;;;;11222:11;;;;;:44;;;11247:19;:17;:19::i;:::-;11237:29;;:7;:29;11222:44;11218:392;;;-1:-1:-1;;;;;11473:19:3;;;:13;:19;;;;;;;;;;;:26;;;;;;;;;:42;;;:49;11417:34;;:119;;:38;:119::i;:::-;-1:-1:-1;;;;;11380:19:3;;;:13;:19;;;;;;;;;;;:26;;;;;;;;;;;:156;;;11557:42;;;11550:49;;;;;-1:-1:-1;;11550:49:3;;;11218:392;11062:554;;;:::o;842:202:28:-;968:68;;;-1:-1:-1;;;;;968:68:28;;;;;;;;;;;;;;;;;;;;;;26:21:-1;;;22:32;;;6:49;;968:68:28;;;;;;;;25:18:-1;;61:17;;-1:-1;;;;;182:15;-1:-1;;;179:29;160:49;;942:95:28;;961:5;;942:18;:95::i;:::-;842:202;;;;:::o;834:176:23:-;892:7;923:5;;;946:6;;;;938:46;;;;;-1:-1:-1;;;938:46:23;;;;;;;;;;;;;;;;;;;;;;;;;;;358:104:22;416:7;446:1;442;:5;:13;;454:1;442:13;;;-1:-1:-1;450:1:22;;358:104;-1:-1:-1;358:104:22:o;1274:134:23:-;1332:7;1358:43;1362:1;1365;1358:43;;;;;;;;;;;;;;;;;:3;:43::i;662:174:28:-;770:58;;;-1:-1:-1;;;;;770:58:28;;;;;;;;;;;;;;;26:21:-1;;;22:32;;;6:49;;770:58:28;;;;;;;;25:18:-1;;61:17;;-1:-1;;;;;182:15;-1:-1;;;179:29;160:49;;744:85:28;;763:5;;2666:1095;3261:27;3269:5;-1:-1:-1;;;;;3261:25:28;;:27::i;:::-;3253:71;;;;;-1:-1:-1;;;3253:71:28;;;;;;;;;;;;;;;;;;;;;;;;;;;;3395:12;3409:23;3444:5;-1:-1:-1;;;;;3436:19:28;3456:4;3436:25;;;;;;;;;;;;;36:153:-1;66:2;61:3;58:11;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;;274:1;267:3;263:2;259:12;254:3;250:22;246:30;315:4;311:9;305:3;299:10;295:26;356:4;350:3;344:10;340:21;389:7;380;377:20;372:3;365:33;3:399;;;3436:25:28;;;;;;;;;;;;;;;;;;;;;;;;14:1:-1;21;16:31;;;;75:4;69:11;64:16;;144:4;140:9;133:4;115:16;111:27;107:43;104:1;100:51;94:4;87:65;169:16;166:1;159:27;225:16;222:1;215:4;212:1;208:12;193:49;7:242;;16:31;36:4;31:9;;7:242;;3394:67:28;;;;3479:7;3471:52;;;;;-1:-1:-1;;;3471:52:28;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3538:17;;:21;3534:221;;3678:10;3667:30;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;3667:30:28;3659:85;;;;-1:-1:-1;;;3659:85:28;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1732:187:23;1818:7;1853:12;1845:6;;;;1837:29;;;;-1:-1:-1;;;1837:29:23;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;1837:29:23;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;1888:5:23;;;1732:187::o;686:610:29:-;746:4;1207:20;;1052:66;1246:23;;;;;;:42;;-1:-1:-1;1273:15:29;;;1246:42;1238:51;686:610;-1:-1:-1;;;;686:610:29:o;649:10969:3:-;;;;;;;;;;-1:-1:-1;649:10969:3;;;;;;;;:::o", "source": "pragma solidity ^0.5.0;\n\nimport \"@openzeppelin/contracts/math/Math.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\";\n\n/** @title Epoch Token Locker\n * EpochTokenLocker saveguards tokens for applications with constant-balances during discrete epochs\n * It allows to deposit a token which become credited in the next epoch and allows to request a token-withdraw\n * which becomes claimable after the current epoch has expired.\n * @author @gnosis/dfusion-team <https://github.com/orgs/gnosis/teams/dfusion-team/members>\n */\ncontract EpochTokenLocker {\n using SafeMath for uint256;\n\n /** @dev Number of seconds a batch is lasting*/\n uint32 public constant BATCH_TIME = 300;\n\n // User => Token => BalanceState\n mapping(address => mapping(address => BalanceState)) private balanceStates;\n\n // user => token => lastCreditBatchId\n mapping(address => mapping(address => uint32)) public lastCreditBatchId;\n\n struct BalanceState {\n uint256 balance;\n PendingFlux pendingDeposits; // deposits will be credited in any future epoch, i.e. currentStateIndex > batchId\n PendingFlux pendingWithdraws; // withdraws are allowed in any future epoch, i.e. currentStateIndex > batchId\n }\n\n struct PendingFlux {\n uint256 amount;\n uint32 batchId;\n }\n\n event Deposit(address indexed user, address indexed token, uint256 amount, uint32 batchId);\n\n event WithdrawRequest(address indexed user, address indexed token, uint256 amount, uint32 batchId);\n\n event Withdraw(address indexed user, address indexed token, uint256 amount);\n\n /** @dev credits user with deposit amount on next epoch (given by getCurrentBatchId)\n * @param token address of token to be deposited\n * @param amount number of token(s) to be credited to user's account\n *\n * Emits an {Deposit} event with relevent deposit information.\n *\n * Requirements:\n * - token transfer to contract is successfull\n */\n function deposit(address token, uint256 amount) public {\n updateDepositsBalance(msg.sender, token);\n SafeERC20.safeTransferFrom(IERC20(token), msg.sender, address(this), amount);\n // solhint-disable-next-line max-line-length\n balanceStates[msg.sender][token].pendingDeposits.amount = balanceStates[msg.sender][token].pendingDeposits.amount.add(\n amount\n );\n balanceStates[msg.sender][token].pendingDeposits.batchId = getCurrentBatchId();\n emit Deposit(msg.sender, token, amount, getCurrentBatchId());\n }\n\n /** @dev Signals and initiates user's intent to withdraw.\n * @param token address of token to be withdrawn\n * @param amount number of token(s) to be withdrawn\n *\n * Emits an {WithdrawRequest} event with relevent request information.\n */\n function requestWithdraw(address token, uint256 amount) public {\n requestFutureWithdraw(token, amount, getCurrentBatchId());\n }\n\n /** @dev Signals and initiates user's intent to withdraw.\n * @param token address of token to be withdrawn\n * @param amount number of token(s) to be withdrawn\n * @param batchId state index at which request is to be made.\n *\n * Emits an {WithdrawRequest} event with relevent request information.\n */\n function requestFutureWithdraw(\n address token,\n uint256 amount,\n uint32 batchId\n ) public {\n // First process pendingWithdraw (if any), as otherwise balances might increase for currentBatchId - 1\n if (hasValidWithdrawRequest(msg.sender, token)) {\n withdraw(msg.sender, token);\n }\n require(batchId >= getCurrentBatchId(), \"Request cannot be made in the past\");\n balanceStates[msg.sender][token].pendingWithdraws = PendingFlux({amount: amount, batchId: batchId});\n emit WithdrawRequest(msg.sender, token, amount, batchId);\n }\n\n /** @dev Claims pending withdraw - can be called on behalf of others\n * @param token address of token to be withdrawn\n * @param user address of user who withdraw is being claimed.\n *\n * Emits an {Withdraw} event stating that `user` withdrew `amount` of `token`\n *\n * Requirements:\n * - withdraw was requested in previous epoch\n * - token was received from exchange in current auction batch\n */\n function withdraw(address user, address token) public {\n updateDepositsBalance(user, token); // withdrawn amount may have been deposited in previous epoch\n require(\n balanceStates[user][token].pendingWithdraws.batchId < getCurrentBatchId(),\n \"withdraw was not registered previously\"\n );\n require(\n lastCreditBatchId[user][token] < getCurrentBatchId(),\n \"Withdraw not possible for token that is traded in the current auction\"\n );\n uint256 amount = Math.min(balanceStates[user][token].balance, balanceStates[user][token].pendingWithdraws.amount);\n\n balanceStates[user][token].balance = balanceStates[user][token].balance.sub(amount);\n delete balanceStates[user][token].pendingWithdraws;\n\n SafeERC20.safeTransfer(IERC20(token), user, amount);\n emit Withdraw(user, token, amount);\n }\n\n /**\n * Public view functions\n */\n /** @dev getter function used to display pending deposit\n * @param user address of user\n * @param token address of ERC20 token\n * return amount and batchId of deposit's transfer if any (else 0)\n */\n function getPendingDeposit(address user, address token) public view returns (uint256, uint32) {\n PendingFlux memory pendingDeposit = balanceStates[user][token].pendingDeposits;\n return (pendingDeposit.amount, pendingDeposit.batchId);\n }\n\n /** @dev getter function used to display pending withdraw\n * @param user address of user\n * @param token address of ERC20 token\n * return amount and batchId when withdraw was requested if any (else 0)\n */\n function getPendingWithdraw(address user, address token) public view returns (uint256, uint32) {\n PendingFlux memory pendingWithdraw = balanceStates[user][token].pendingWithdraws;\n return (pendingWithdraw.amount, pendingWithdraw.batchId);\n }\n\n /** @dev getter function to determine current auction id.\n * return current batchId\n */\n function getCurrentBatchId() public view returns (uint32) {\n // solhint-disable-next-line not-rely-on-time\n return uint32(now / BATCH_TIME);\n }\n\n /** @dev used to determine how much time is left in a batch\n * return seconds remaining in current batch\n */\n function getSecondsRemainingInBatch() public view returns (uint256) {\n // solhint-disable-next-line not-rely-on-time\n return BATCH_TIME - (now % BATCH_TIME);\n }\n\n /** @dev fetches and returns user's balance\n * @param user address of user\n * @param token address of ERC20 token\n * return Current `token` balance of `user`'s account\n */\n function getBalance(address user, address token) public view returns (uint256) {\n uint256 balance = balanceStates[user][token].balance;\n if (balanceStates[user][token].pendingDeposits.batchId < getCurrentBatchId()) {\n balance = balance.add(balanceStates[user][token].pendingDeposits.amount);\n }\n if (balanceStates[user][token].pendingWithdraws.batchId < getCurrentBatchId()) {\n balance = balance.sub(Math.min(balanceStates[user][token].pendingWithdraws.amount, balance));\n }\n return balance;\n }\n\n /** @dev Used to determine if user has a valid pending withdraw request of specific token\n * @param user address of user\n * @param token address of ERC20 token\n * return true if `user` has valid withdraw request for `token`, otherwise false\n */\n function hasValidWithdrawRequest(address user, address token) public view returns (bool) {\n return\n balanceStates[user][token].pendingWithdraws.batchId < getCurrentBatchId() &&\n balanceStates[user][token].pendingWithdraws.batchId > 0;\n }\n\n /**\n * internal functions\n */\n /**\n * The following function should be used to update any balances within an epoch, which\n * will not be immediately final. E.g. the BatchExchange credits new balances to\n * the buyers in an auction, but as there are might be better solutions, the updates are\n * not final. In order to prevent withdraws from non-final updates, we disallow withdraws\n * by setting lastCreditBatchId to the current batchId and allow only withdraws in batches\n * with a higher batchId.\n */\n function addBalanceAndBlockWithdrawForThisBatch(\n address user,\n address token,\n uint256 amount\n ) internal {\n if (hasValidWithdrawRequest(user, token)) {\n lastCreditBatchId[user][token] = getCurrentBatchId();\n }\n addBalance(user, token, amount);\n }\n\n function addBalance(\n address user,\n address token,\n uint256 amount\n ) internal {\n updateDepositsBalance(user, token);\n balanceStates[user][token].balance = balanceStates[user][token].balance.add(amount);\n }\n\n /**\n * The following function should be used to subtract amounts from the current balances state.\n * For the substraction the current withdrawRequests are considered and they are effectively reducing\n * the available balance.\n */\n function subtractBalance(\n address user,\n address token,\n uint256 amount\n ) internal {\n require(amount <= getBalance(user, token), \"Amount exceeds user's balance.\");\n subtractBalanceUnchecked(user, token, amount);\n }\n\n /**\n * The following function should be used to substract amounts from the current balance\n * state, if the pending withdrawRequests are not considered and should not effectively reduce\n * the available balance.\n * For example, the reversion of trades from a previous batch-solution do not\n * need to consider withdrawRequests. This is the case as withdraws are blocked for one\n * batch for accounts having credited funds in a previous submission.\n * PendingWithdraws must also be ignored since otherwise for the reversion of trades,\n * a solution reversion could be blocked: A bigger withdrawRequest could set the return value of\n * getBalance(user, token) to zero, although the user was just credited tokens in\n * the last submission. In this situation, during the unwinding of the previous orders,\n * the check `amount <= getBalance(user, token)` would fail and the reversion would be blocked.\n */\n function subtractBalanceUnchecked(\n address user,\n address token,\n uint256 amount\n ) internal {\n updateDepositsBalance(user, token);\n balanceStates[user][token].balance = balanceStates[user][token].balance.sub(amount);\n }\n\n function updateDepositsBalance(address user, address token) private {\n uint256 batchId = balanceStates[user][token].pendingDeposits.batchId;\n if (batchId > 0 && batchId < getCurrentBatchId()) {\n // batchId > 0 is checked in order save an SSTORE in case there is no pending deposit\n balanceStates[user][token].balance = balanceStates[user][token].balance.add(\n balanceStates[user][token].pendingDeposits.amount\n );\n delete balanceStates[user][token].pendingDeposits;\n }\n }\n}\n", "sourcePath": "/Users/felixleupold/Gnosis/dex-contracts/contracts/EpochTokenLocker.sol", "ast": { "absolutePath": "/Users/felixleupold/Gnosis/dex-contracts/contracts/EpochTokenLocker.sol", "exported