commit b5fbc778c040b4fdbd17381f5d7eae78dee52ad4
parent a4fc3c1ddaf645d4c67633b98fd3ce0b81a5c4e0
Author: lash <dev@holbrook.no>
Date: Wed, 26 Jul 2023 17:02:01 +0100
Implement python interface, deposit and swap test
Diffstat:
14 files changed, 394 insertions(+), 8 deletions(-)
diff --git a/.gitignore b/.gitignore
@@ -0,0 +1,7 @@
+__pycache__
+*.pyc
+*.egg-info
+build/
+dist/
+solidity/*.json
+solidity/*.bin
diff --git a/python/erc20_pool/__init__.py b/python/erc20_pool/__init__.py
@@ -0,0 +1 @@
+from .pool import Pool
diff --git a/python/erc20_pool/data/SwapPool.bin b/python/erc20_pool/data/SwapPool.bin
@@ -0,0 +1 @@
+60a06040523480156200001157600080fd5b5060405162002a9c38038062002a9c83398181016040528101906200003791906200032a565b846006908162000048919062000641565b5083600790816200005a919062000641565b508260ff166080818152505080600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555081600581905550505050505062000728565b6000604051905090565b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6200012282620000d7565b810181811067ffffffffffffffff82111715620001445762000143620000e8565b5b80604052505050565b600062000159620000b9565b905062000167828262000117565b919050565b600067ffffffffffffffff8211156200018a5762000189620000e8565b5b6200019582620000d7565b9050602081019050919050565b60005b83811015620001c2578082015181840152602081019050620001a5565b60008484015250505050565b6000620001e5620001df846200016c565b6200014d565b905082815260208101848484011115620002045762000203620000d2565b5b62000211848285620001a2565b509392505050565b600082601f830112620002315762000230620000cd565b5b815162000243848260208601620001ce565b91505092915050565b600060ff82169050919050565b62000264816200024c565b81146200027057600080fd5b50565b600081519050620002848162000259565b92915050565b6000819050919050565b6200029f816200028a565b8114620002ab57600080fd5b50565b600081519050620002bf8162000294565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000620002f282620002c5565b9050919050565b6200030481620002e5565b81146200031057600080fd5b50565b6000815190506200032481620002f9565b92915050565b600080600080600060a08688031215620003495762000348620000c3565b5b600086015167ffffffffffffffff8111156200036a5762000369620000c8565b5b620003788882890162000219565b955050602086015167ffffffffffffffff8111156200039c576200039b620000c8565b5b620003aa8882890162000219565b9450506040620003bd8882890162000273565b9350506060620003d088828901620002ae565b9250506080620003e38882890162000313565b9150509295509295909350565b600081519050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806200044357607f821691505b602082108103620004595762000458620003fb565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b60008160020a8302905092915050565b600060088302620004c67fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8262000484565b620004d2868362000484565b95508019841693508086168417925050509392505050565b6000819050919050565b6000819050919050565b60006200051f620005196200051384620004ea565b620004f4565b620004ea565b9050919050565b6000819050919050565b6200053b83620004fe565b620005536200054a8262000526565b84845462000494565b825550505050565b600090565b6200056a6200055b565b6200057781848462000530565b505050565b5b818110156200059f576200059360008262000560565b6001810190506200057d565b5050565b601f821115620005ee57620005b8816200045f565b620005c38462000474565b81016020851015620005d3578190505b620005eb620005e28562000474565b8301826200057c565b50505b505050565b60008160020a8304905092915050565b60006200061660001984600802620005f3565b1980831691505092915050565b600062000631838362000603565b9150826002028217905092915050565b6200064c82620003f0565b67ffffffffffffffff811115620006685762000667620000e8565b5b6200067482546200042a565b62000681828285620005a3565b600060209050601f831160018114620006b95760008415620006a4578287015190505b620006b0858262000623565b86555062000720565b601f198416620006c9866200045f565b60005b82811015620006f357848901518255600182019150602085019450602081019050620006cc565b868310156200071357848901516200070f601f89168262000603565b8355505b6001600288020188555050505b505050505050565b60805161235862000744600039600061055f01526123586000f3fe608060405234801561001057600080fd5b5060043610610128576000357c01000000000000000000000000000000000000000000000000000000009004806351cff8d9116100bf5780638da5cb5b1161008e5780638da5cb5b146102d757806395d89b41146102f5578063d9caed1214610313578063f2fde38b1461032f578063f3fef3a31461035f57610128565b806351cff8d91461023f57806369fe0e2d1461026f57806386fe212d1461028b5780638705fcd4146102bb57610128565b80632c1758c1116100fb5780632c1758c1146101b7578063313ce567146101e757806331a5995d1461020557806347e7ef241461022357610128565b806301ffc9a71461012d57806306fdde031461015d57806318160ddd1461017b57806318cbbcfc14610199575b600080fd5b610147600480360381019061014291906117ba565b61038f565b6040516101549190611802565b60405180910390f35b610165610491565b60405161017291906118ad565b60405180910390f35b61018361051f565b60405161019091906118e8565b60405180910390f35b6101a1610525565b6040516101ae91906118e8565b60405180910390f35b6101d160048036038101906101cc919061192f565b61052a565b6040516101de9190611802565b60405180910390f35b6101ef61055d565b6040516101fc91906118e8565b60405180910390f35b61020d610581565b60405161021a91906118e8565b60405180910390f35b61023d600480360381019061023891906119ba565b610587565b005b610259600480360381019061025491906119fa565b61076d565b60405161026691906118e8565b60405180910390f35b6102896004803603810190610284919061192f565b6107c4565b005b6102a560048036038101906102a0919061192f565b6108ee565b6040516102b291906118e8565b60405180910390f35b6102d560048036038101906102d091906119fa565b6109d6565b005b6102df610af5565b6040516102ec9190611a36565b60405180910390f35b6102fd610b19565b60405161030a91906118ad565b60405180910390f35b61032d60048036038101906103289190611a51565b610ba7565b005b610349600480360381019061034491906119fa565b610fcd565b6040516103569190611802565b60405180910390f35b610379600480360381019061037491906119ba565b61110f565b60405161038691906118e8565b60405180910390f35b60006301ffc9a77c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916036103e3576001905061048c565b639493f8b27c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191603610435576001905061048c565b630d7491f87c010000000000000000000000000000000000000000000000000000000002827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191603610487576001905061048c565b600090505b919050565b6006805461049e90611ad3565b80601f01602080910402602001604051908101604052809291908181526020018280546104ca90611ad3565b80156105175780601f106104ec57610100808354040283529160200191610517565b820191906000526020600020905b8154815290600101906020018083116104fa57829003601f168201915b505050505081565b60085481565b600381565b60006003821061053957600080fd5b6000820361054e576003600a54149050610558565b81600a5483161490505b919050565b7f000000000000000000000000000000000000000000000000000000000000000081565b600a5481565b600060606105b784600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16611369565b8373ffffffffffffffffffffffffffffffffffffffff163330856040516024016105e393929190611b63565b6040516020818303038152906040527f23b872dd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505060405161066d9190611be1565b6000604051808303816000865af19150503d80600081146106aa576040519150601f19603f3d011682016040523d82523d6000602084013e6106af565b606091505b508092508193505050816106f8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106ef90611c44565b60405180910390fd5b8080602001905181019061070c9190611c90565b91508161074e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161074590611d09565b60405180910390fd5b82600860008282546107609190611d58565b9250508190555050505050565b600080600960008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490506107bc838261110f565b915050919050565b6107d1600160ff1661052a565b15610811576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161080890611dd8565b60405180910390fd5b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461089f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161089690611e44565b60405180910390fd5b620f424081106108e4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108db90611eb0565b60405180910390fd5b8060038190555050565b60006003821115610934576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161092b90611f1c565b60405180910390fd5b6000600a5483161461097b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161097290611f88565b60405180910390fd5b81600a600082825417925050819055506003600a541415157f6b7e2e653f93b645d4ed7292d6429f96637084363e477c8aaea1a43ed13c284e600a546040516109c491906118e8565b60405180910390a2600a549050919050565b6109e3600260ff1661052a565b15610a23576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a1a90611dd8565b60405180910390fd5b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610ab1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610aa890611e44565b60405180910390fd5b80600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60078054610b2690611ad3565b80601f0160208091040260200160405190810160405280929190818152602001828054610b5290611ad3565b8015610b9f5780601f10610b7457610100808354040283529160200191610b9f565b820191906000526020600020905b815481529060010190602001808311610b8257829003601f168201915b505050505081565b600060606000806000610bb986611542565b90508086610bc79190611fa8565b9250610bd488888561156f565b92508773ffffffffffffffffffffffffffffffffffffffff1630604051602401610bfe9190611fdc565b6040516020818303038152906040527f70a08231000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050604051610c889190611be1565b6000604051808303816000865af19150503d8060008114610cc5576040519150601f19603f3d011682016040523d82523d6000602084013e610cca565b606091505b50809550819650505084610d13576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d0a90611c44565b60405180910390fd5b83806020019051810190610d27919061200c565b91508083610d359190611d58565b821015610d77576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d6e90612085565b60405180910390fd5b610d818787610587565b8773ffffffffffffffffffffffffffffffffffffffff163384604051602401610dab9291906120a5565b6040516020818303038152906040527fa9059cbb000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050604051610e359190611be1565b6000604051808303816000865af19150503d8060008114610e72576040519150601f19603f3d011682016040523d82523d6000602084013e610e77565b606091505b50809550819650505084610ec0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610eb790611c44565b60405180910390fd5b83806020019051810190610ed49190611c90565b945084610f16576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f0d90611d09565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610fc35780600960008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254610fbb9190611d58565b925050819055505b5050505050505050565b60008060008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461102857600080fd5b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050826000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a36001915050919050565b6000806060600073ffffffffffffffffffffffffffffffffffffffff16600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16036111a5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161119c90611e44565b60405180910390fd5b8473ffffffffffffffffffffffffffffffffffffffff1630600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16866040516024016111f3939291906120ce565b6040516020818303038152906040527f23b872dd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505060405161127d9190611be1565b6000604051808303816000865af19150503d80600081146112ba576040519150601f19603f3d011682016040523d82523d6000602084013e6112bf565b606091505b50809250819350505081611308576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112ff90611c44565b60405180910390fd5b8080602001905181019061131c9190611c90565b91508161135e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161135590611d09565b60405180910390fd5b839250505092915050565b60006060600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036113a857505061153e565b8273ffffffffffffffffffffffffffffffffffffffff16846040516024016113d09190611a36565b6040516020818303038152906040527f3ef25013000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505060405161145a9190611be1565b6000604051808303816000865af19150503d8060008114611497576040519150601f19603f3d011682016040523d82523d6000602084013e61149c565b606091505b508092508193505050816114e5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114dc90612151565b60405180910390fd5b808060200190518101906114f99190611c90565b91508161153b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611532906121bd565b60405180910390fd5b50505b5050565b6000806003548361155391906121dd565b9050620f424081611564919061224e565b905080915050919050565b600080606060008073ffffffffffffffffffffffffffffffffffffffff16600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16036115d657849350505050611756565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168787876040516024016116249392919061227f565b6040516020818303038152906040527fdbb21d40000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040516116ae9190611be1565b6000604051808303816000865af19150503d80600081146116eb576040519150601f19603f3d011682016040523d82523d6000602084013e6116f0565b606091505b50809350819450505082611739576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161173090612302565b60405180910390fd5b8180602001905181019061174d919061200c565b90508093505050505b9392505050565b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61179781611762565b81146117a257600080fd5b50565b6000813590506117b48161178e565b92915050565b6000602082840312156117d0576117cf61175d565b5b60006117de848285016117a5565b91505092915050565b60008115159050919050565b6117fc816117e7565b82525050565b600060208201905061181760008301846117f3565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b8381101561185757808201518184015260208101905061183c565b60008484015250505050565b6000601f19601f8301169050919050565b600061187f8261181d565b6118898185611828565b9350611899818560208601611839565b6118a281611863565b840191505092915050565b600060208201905081810360008301526118c78184611874565b905092915050565b6000819050919050565b6118e2816118cf565b82525050565b60006020820190506118fd60008301846118d9565b92915050565b61190c816118cf565b811461191757600080fd5b50565b60008135905061192981611903565b92915050565b6000602082840312156119455761194461175d565b5b60006119538482850161191a565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006119878261195c565b9050919050565b6119978161197c565b81146119a257600080fd5b50565b6000813590506119b48161198e565b92915050565b600080604083850312156119d1576119d061175d565b5b60006119df858286016119a5565b92505060206119f08582860161191a565b9150509250929050565b600060208284031215611a1057611a0f61175d565b5b6000611a1e848285016119a5565b91505092915050565b611a308161197c565b82525050565b6000602082019050611a4b6000830184611a27565b92915050565b600080600060608486031215611a6a57611a6961175d565b5b6000611a78868287016119a5565b9350506020611a89868287016119a5565b9250506040611a9a8682870161191a565b9150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680611aeb57607f821691505b602082108103611afe57611afd611aa4565b5b50919050565b6000819050919050565b6000611b29611b24611b1f8461195c565b611b04565b61195c565b9050919050565b6000611b3b82611b0e565b9050919050565b6000611b4d82611b30565b9050919050565b611b5d81611b42565b82525050565b6000606082019050611b786000830186611a27565b611b856020830185611b54565b611b9260408301846118d9565b949350505050565b600081519050919050565b600081905092915050565b6000611bbb82611b9a565b611bc58185611ba5565b9350611bd5818560208601611839565b80840191505092915050565b6000611bed8284611bb0565b915081905092915050565b7f4552525f544f4b454e0000000000000000000000000000000000000000000000600082015250565b6000611c2e600983611828565b9150611c3982611bf8565b602082019050919050565b60006020820190508181036000830152611c5d81611c21565b9050919050565b611c6d816117e7565b8114611c7857600080fd5b50565b600081519050611c8a81611c64565b92915050565b600060208284031215611ca657611ca561175d565b5b6000611cb484828501611c7b565b91505092915050565b7f4552525f5452414e534645520000000000000000000000000000000000000000600082015250565b6000611cf3600c83611828565b9150611cfe82611cbd565b602082019050919050565b60006020820190508181036000830152611d2281611ce6565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000611d63826118cf565b9150611d6e836118cf565b9250828201905080821115611d8657611d85611d29565b5b92915050565b7f4552525f5345414c000000000000000000000000000000000000000000000000600082015250565b6000611dc2600883611828565b9150611dcd82611d8c565b602082019050919050565b60006020820190508181036000830152611df181611db5565b9050919050565b7f4552525f41585800000000000000000000000000000000000000000000000000600082015250565b6000611e2e600783611828565b9150611e3982611df8565b602082019050919050565b60006020820190508181036000830152611e5d81611e21565b9050919050565b7f4552525f4645455f544f4f5f4849474800000000000000000000000000000000600082015250565b6000611e9a601083611828565b9150611ea582611e64565b602082019050919050565b60006020820190508181036000830152611ec981611e8d565b9050919050565b7f4552525f494e56414c49445f5354415445000000000000000000000000000000600082015250565b6000611f06601183611828565b9150611f1182611ed0565b602082019050919050565b60006020820190508181036000830152611f3581611ef9565b9050919050565b7f4552525f414c52454144595f4c4f434b45440000000000000000000000000000600082015250565b6000611f72601283611828565b9150611f7d82611f3c565b602082019050919050565b60006020820190508181036000830152611fa181611f65565b9050919050565b6000611fb3826118cf565b9150611fbe836118cf565b9250828203905081811115611fd657611fd5611d29565b5b92915050565b6000602082019050611ff16000830184611b54565b92915050565b60008151905061200681611903565b92915050565b6000602082840312156120225761202161175d565b5b600061203084828501611ff7565b91505092915050565b7f4552525f42414c414e4345000000000000000000000000000000000000000000600082015250565b600061206f600b83611828565b915061207a82612039565b602082019050919050565b6000602082019050818103600083015261209e81612062565b9050919050565b60006040820190506120ba6000830185611a27565b6120c760208301846118d9565b9392505050565b60006060820190506120e36000830186611b54565b6120f06020830185611a27565b6120fd60408301846118d9565b949350505050565b7f4552525f52454749535452590000000000000000000000000000000000000000600082015250565b600061213b600c83611828565b915061214682612105565b602082019050919050565b6000602082019050818103600083015261216a8161212e565b9050919050565b7f4552525f554e415554485f544f4b454e00000000000000000000000000000000600082015250565b60006121a7601083611828565b91506121b282612171565b602082019050919050565b600060208201905081810360008301526121d68161219a565b9050919050565b60006121e8826118cf565b91506121f3836118cf565b9250828202612201816118cf565b9150828204841483151761221857612217611d29565b5b5092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000612259826118cf565b9150612264836118cf565b9250826122745761227361221f565b5b828204905092915050565b60006060820190506122946000830186611a27565b6122a16020830185611a27565b6122ae60408301846118d9565b949350505050565b7f4552525f51554f54455200000000000000000000000000000000000000000000600082015250565b60006122ec600a83611828565b91506122f7826122b6565b602082019050919050565b6000602082019050818103600083015261231b816122df565b905091905056fea2646970667358221220d38fee131e8fea6c9d1b9f58721fb65c2c5eb44a9498caf17e179a79ef7e9b6764736f6c63430008130033
+\ No newline at end of file
diff --git a/python/erc20_pool/data/SwapPool.json b/python/erc20_pool/data/SwapPool.json
@@ -0,0 +1 @@
+[{"inputs":[{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_symbol","type":"string"},{"internalType":"uint8","name":"_decimals","type":"uint8"},{"internalType":"bytes32","name":"_declaration","type":"bytes32"},{"internalType":"address","name":"_tokenRegistry","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bool","name":"_final","type":"bool"},{"indexed":false,"internalType":"uint256","name":"_sealState","type":"uint256"}],"name":"SealStateChange","type":"event"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"deposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_state","type":"uint256"}],"name":"isSealed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSealState","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_state","type":"uint256"}],"name":"seal","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"sealState","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_fee","type":"uint256"}],"name":"setFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_feeAddress","type":"address"}],"name":"setFeeAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"_sum","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_newOwner","type":"address"}],"name":"transferOwnership","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_outToken","type":"address"}],"name":"withdraw","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_outToken","type":"address"},{"internalType":"address","name":"_inToken","type":"address"},{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_outToken","type":"address"},{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"withdraw","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"}]
diff --git a/python/erc20_pool/data/SwapPool.metadata.json b/python/erc20_pool/data/SwapPool.metadata.json
@@ -0,0 +1 @@
+{"compiler":{"version":"0.8.19+commit.7dd6d404"},"language":"Solidity","output":{"abi":[{"inputs":[{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_symbol","type":"string"},{"internalType":"uint8","name":"_decimals","type":"uint8"},{"internalType":"bytes32","name":"_declaration","type":"bytes32"},{"internalType":"address","name":"_tokenRegistry","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bool","name":"_final","type":"bool"},{"indexed":false,"internalType":"uint256","name":"_sealState","type":"uint256"}],"name":"SealStateChange","type":"event"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"deposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_state","type":"uint256"}],"name":"isSealed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSealState","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_state","type":"uint256"}],"name":"seal","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"sealState","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_fee","type":"uint256"}],"name":"setFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_feeAddress","type":"address"}],"name":"setFeeAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"_sum","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_newOwner","type":"address"}],"name":"transferOwnership","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_outToken","type":"address"}],"name":"withdraw","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_outToken","type":"address"},{"internalType":"address","name":"_inToken","type":"address"},{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_outToken","type":"address"},{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"withdraw","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"}],"devdoc":{"kind":"dev","methods":{},"version":1},"userdoc":{"kind":"user","methods":{},"version":1}},"settings":{"compilationTarget":{"SwapPool.sol":"SwapPool"},"evmVersion":"byzantium","libraries":{},"metadata":{"bytecodeHash":"ipfs"},"optimizer":{"enabled":false,"runs":200},"remappings":[]},"sources":{"SwapPool.sol":{"keccak256":"0xe353d1255baee8fd9937c51600b0710e041108f041062a0130e6833a51c5c873","license":"AGPL-3.0-or-later","urls":["bzz-raw://56811f458f4310e26fbe8cf177eff3165898f324bfe74a6ca954771d20f3b498","dweb:/ipfs/QmYa1bep3hAvcNr7w1PHjRa65CLUkcJKmZRftKXZGG8wwS"]}},"version":1}
diff --git a/python/erc20_pool/data/__init__.py b/python/erc20_pool/data/__init__.py
@@ -0,0 +1,3 @@
+import os
+
+data_dir = os.path.realpath(os.path.dirname(__file__))
diff --git a/python/erc20_pool/pool.py b/python/erc20_pool/pool.py
@@ -0,0 +1,119 @@
+# standard imports
+import logging
+import os
+import enum
+
+# external imports
+from chainlib.eth.constant import ZERO_ADDRESS
+from chainlib.eth.constant import ZERO_CONTENT
+from chainlib.eth.contract import (
+ ABIContractEncoder,
+ ABIContractDecoder,
+ ABIContractType,
+ abi_decode_single,
+)
+from chainlib.eth.jsonrpc import to_blockheight_param
+from chainlib.eth.error import RequestMismatchException
+from chainlib.eth.tx import (
+ TxFactory,
+ TxFormat,
+)
+from chainlib.jsonrpc import JSONRPCRequest
+from chainlib.block import BlockSpec
+from hexathon import (
+ add_0x,
+ strip_0x,
+)
+from chainlib.eth.cli.encode import CLIEncoder
+
+# local imports
+from erc20_pool.data import data_dir
+
+logg = logging.getLogger()
+
+
+class Pool(TxFactory):
+
+ __abi = None
+ __bytecode = None
+
+ def constructor(self, sender_address, name, symbol, decimals, declaration=None, accounts_registry=None, tx_format=TxFormat.JSONRPC, version=None):
+ code = self.cargs(name, symbol, decimals, declaration=declaration, accounts_registry=accounts_registry, version=version)
+ tx = self.template(sender_address, None, use_nonce=True)
+ tx = self.set_code(tx, code)
+ return self.finalize(tx, tx_format)
+
+
+ @staticmethod
+ def cargs(name, symbol, decimals, declaration=None, accounts_registry=None, version=None):
+ if declaration == None:
+ declaration = ZERO_CONTENT
+ if accounts_registry == None:
+ accounts_registry = ZERO_ADDRESS
+ code = Pool.bytecode(version=version)
+ enc = ABIContractEncoder()
+ enc.string(name)
+ enc.string(symbol)
+ enc.uint256(decimals)
+ enc.bytes32(declaration)
+ enc.address(accounts_registry)
+ args = enc.get()
+ code += args
+ logg.debug('constructor code: ' + args)
+ return code
+
+
+ @staticmethod
+ def gas(code=None):
+ return 4000000
+
+
+ @staticmethod
+ def abi():
+ if Pool.__abi == None:
+ f = open(os.path.join(data_dir, 'SwapPool.json'), 'r')
+ Pool.__abi = json.load(f)
+ f.close()
+ return Pool.__abi
+
+
+ @staticmethod
+ def bytecode(version=None):
+ if Pool.__bytecode == None:
+ f = open(os.path.join(data_dir, 'SwapPool.bin'))
+ Pool.__bytecode = f.read()
+ f.close()
+ return Pool.__bytecode
+
+
+ def deposit(self, contract_address, sender_address, token_address, value, tx_format=TxFormat.JSONRPC, id_generator=None):
+ enc = ABIContractEncoder()
+ enc.method('deposit')
+ enc.typ(ABIContractType.ADDRESS)
+ enc.typ(ABIContractType.UINT256)
+ enc.address(token_address)
+ enc.uint256(value)
+ data = add_0x(enc.get())
+ tx = self.template(sender_address, contract_address, use_nonce=True)
+ tx = self.set_code(tx, data)
+ tx = self.finalize(tx, tx_format, id_generator=id_generator)
+ return tx
+
+
+ def swap(self, contract_address, sender_address, token_address_out, token_address_in, value, tx_format=TxFormat.JSONRPC, id_generator=None):
+ enc = ABIContractEncoder()
+ enc.method('withdraw')
+ enc.typ(ABIContractType.ADDRESS)
+ enc.typ(ABIContractType.ADDRESS)
+ enc.typ(ABIContractType.UINT256)
+ enc.address(token_address_out)
+ enc.address(token_address_in)
+ enc.uint256(value)
+ data = add_0x(enc.get())
+ tx = self.template(sender_address, contract_address, use_nonce=True)
+ tx = self.set_code(tx, data)
+ tx = self.finalize(tx, tx_format, id_generator=id_generator)
+ return tx
+
+
+
diff --git a/python/erc20_pool/unittest/__init__.py b/python/erc20_pool/unittest/__init__.py
@@ -0,0 +1 @@
+from .base import *
diff --git a/python/erc20_pool/unittest/base.py b/python/erc20_pool/unittest/base.py
@@ -0,0 +1,63 @@
+# standard imports
+import logging
+import time
+
+# external imports
+from chainlib.eth.unittest.ethtester import EthTesterCase
+from chainlib.connection import RPCConnection
+from chainlib.eth.nonce import RPCNonceOracle
+from chainlib.eth.tx import receipt
+from chainlib.eth.address import to_checksum_address
+from giftable_erc20_token.unittest import TestGiftableToken
+from eth_erc20 import ERC20
+from chainlib.eth.block import block_latest
+from eth_accounts_index.unittest import TestAccountsIndex
+from eth_accounts_index.registry import AccountRegistry
+from giftable_erc20_token import GiftableToken
+
+# local imports
+from erc20_pool import Pool
+
+logg = logging.getLogger(__name__)
+
+hash_of_foo = '2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae'
+hash_of_bar = 'fcde2b2edba56bf408601fb721fe9b5c338d10ee429ea04fae5511b68fbf8fb9'
+hash_of_baz = 'baa5a0964d3320fbc0c6a922140453c8513ea24ab8fd0577034804a967248096'
+
+
+class TestERC20Pool(TestGiftableToken):
+
+ expire = 0
+
+ def setUp(self):
+ super(TestERC20Pool, self).setUp()
+
+ self.foo_address = self.address
+ self.bar_address = self.publish_giftable_token('Bar Token', 'BAR', 16)
+ self.baz_address = self.publish_giftable_token('Baz Token', 'BAZ', 16)
+ self.initial_supply_bar = 1 << 20
+ self.initial_supply_baz = 1 << 15
+
+ nonce_oracle = RPCNonceOracle(self.accounts[0], conn=self.conn)
+ c = GiftableToken(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle)
+ (tx_hash, o) = c.mint_to(self.bar_address, self.accounts[0], self.accounts[1], self.initial_supply_bar)
+ r = self.conn.do(o)
+ o = receipt(tx_hash)
+ r = self.conn.do(o)
+ self.assertEqual(r['status'], 1)
+
+ (tx_hash, o) = c.mint_to(self.baz_address, self.accounts[0], self.accounts[2], self.initial_supply_baz)
+ r = self.conn.do(o)
+ o = receipt(tx_hash)
+ r = self.conn.do(o)
+ self.assertEqual(r['status'], 1)
+
+ c = Pool(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle)
+ (tx_hash, o) = c.constructor(self.accounts[0], "Big Pool", "BIG", 16)
+ self.rpc.do(o)
+ o = receipt(tx_hash)
+ r = self.rpc.do(o)
+ self.assertEqual(r['status'], 1)
+ self.voter_address = to_checksum_address(r['contract_address'])
+ logg.debug('published bar token {}, baz token {}'.format(self.bar_address, self.baz_address))
+ logg.debug('published voter on address {} with hash {}'.format(self.voter_address, tx_hash))
diff --git a/python/requirements.txt b/python/requirements.txt
@@ -0,0 +1,3 @@
+eth-erc20~=0.7.3
+chainlib-eth~=0.4.22
+#chainlib~=0.4.14
diff --git a/python/test_requirements.txt b/python/test_requirements.txt
@@ -0,0 +1,4 @@
+eth_tester==0.5.0b3
+py-evm==0.3.0a20
+eth-interface==0.1.1
+eth-accounts-index~=0.5.3
diff --git a/python/tests/test_base.py b/python/tests/test_base.py
@@ -0,0 +1,77 @@
+# standard imports
+import unittest
+import logging
+import os
+from chainlib.eth.nonce import RPCNonceOracle
+from chainlib.eth.tx import receipt
+from chainlib.eth.block import block_latest
+from hexathon import same as same_hex
+from eth_erc20 import ERC20
+from giftable_erc20_token import GiftableToken
+
+# local imports
+from erc20_pool.unittest import TestERC20Pool
+from erc20_pool import Pool
+#from evm_tokenvote.unittest.base import hash_of_foo
+#from evm_tokenvote import Voter
+#from evm_tokenvote import ProposalState
+
+
+logging.basicConfig(level=logging.DEBUG)
+logg = logging.getLogger()
+
+class TestPoolBase(TestERC20Pool):
+
+ def test_deposit(self):
+ nonce_oracle = RPCNonceOracle(self.accounts[0], conn=self.conn)
+ c = ERC20(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle)
+ (tx_hash, o) = c.approve(self.foo_address, self.accounts[0], self.voter_address, 1024)
+ self.rpc.do(o)
+
+ c = Pool(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle)
+ (tx_hash, o) = c.deposit(self.voter_address, self.accounts[0], self.foo_address, 1024)
+ self.rpc.do(o)
+ o = receipt(tx_hash)
+ r = self.rpc.do(o)
+ self.assertEqual(r['status'], 1)
+
+ c = ERC20(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle)
+ o = c.balance_of(self.foo_address, self.voter_address, sender_address=self.accounts[0])
+ r = self.rpc.do(o)
+ self.assertEqual(int(r, 16), 1024)
+
+
+ def test_swap(self):
+ nonce_oracle = RPCNonceOracle(self.accounts[0], conn=self.conn)
+ c = ERC20(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle)
+ (tx_hash, o) = c.approve(self.foo_address, self.accounts[0], self.voter_address, 1024)
+ self.rpc.do(o)
+
+ c = Pool(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle)
+ (tx_hash, o) = c.deposit(self.voter_address, self.accounts[0], self.foo_address, 1024)
+ self.rpc.do(o)
+
+ nonce_oracle = RPCNonceOracle(self.accounts[1], conn=self.conn)
+ c = ERC20(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle)
+ (tx_hash, o) = c.approve(self.bar_address, self.accounts[1], self.voter_address, 768)
+ self.rpc.do(o)
+
+ c = ERC20(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle)
+ (tx_hash, o) = c.approve(self.foo_address, self.accounts[1], self.voter_address, 768)
+ self.rpc.do(o)
+
+ c = Pool(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle)
+ (tx_hash, o) = c.swap(self.voter_address, self.accounts[1], self.foo_address, self.bar_address, 768)
+ self.rpc.do(o)
+ o = receipt(tx_hash)
+ r = self.rpc.do(o)
+ self.assertEqual(r['status'], 1)
+
+ c = ERC20(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle)
+ o = c.balance_of(self.foo_address, self.accounts[1], sender_address=self.accounts[0])
+ r = self.rpc.do(o)
+ self.assertEqual(int(r, 16), 768)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/solidity/Makefile b/solidity/Makefile
@@ -7,6 +7,6 @@ all:
truncate -s -1 SwapPool.bin
install: all
- cp -v *.json ../python/erc20_swap_pool/data/
- cp -v *.bin ../python/erc20_swap_pool/data/
+ cp -v *.json ../python/erc20_pool/data/
+ cp -v *.bin ../python/erc20_pool/data/
diff --git a/solidity/SwapPool.sol b/solidity/SwapPool.sol
@@ -6,27 +6,98 @@ pragma solidity ^0.8.0;
// Description: Voting contract using ERC20 tokens as shares
contract SwapPool {
+ // Implements EIP173
+ address public owner;
+
address registry;
address quoter;
uint256 feePpm;
address feeAddress;
+ bytes32 declaration;
+
+ string public name;
+ string public symbol;
+ uint256 public immutable decimals;
+
uint256 public totalSupply;
+
mapping ( address => uint256 ) fees;
-
- constructor(address _tokenRegistry) {
+
+ // Implements Seal
+ uint256 public sealState;
+ uint8 constant FEE_STATE = 1;
+ uint8 constant FEEADDRESS_STATE = 2;
+ uint256 constant public maxSealState = 3;
+
+ // Implements Seal
+ event SealStateChange(bool indexed _final, uint256 _sealState);
+
+ // EIP173
+ event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); // EIP173
+
+ constructor(string memory _name, string memory _symbol, uint8 _decimals, bytes32 _declaration, address _tokenRegistry) {
+ name = _name;
+ symbol = _symbol;
+ decimals = _decimals;
registry = _tokenRegistry;
+ declaration = _declaration;
+ }
+
+ function seal(uint256 _state) public returns(uint256) {
+ require(_state <= maxSealState, 'ERR_INVALID_STATE');
+ require(_state & sealState == 0, 'ERR_ALREADY_LOCKED');
+ sealState |= _state;
+ emit SealStateChange(sealState == maxSealState, sealState);
+ return uint256(sealState);
+ }
+
+ function isSealed(uint256 _state) public view returns(bool) {
+ require(_state < maxSealState);
+ if (_state == 0) {
+ return sealState == maxSealState;
+ }
+ return _state & sealState == _state;
+ }
+
+ // Change address for collecting fees
+ function setFeeAddress(address _feeAddress) public {
+ require(!isSealed(FEEADDRESS_STATE), "ERR_SEAL");
+ require(msg.sender == owner, "ERR_AXX");
+ feeAddress = _feeAddress;
+ }
+
+ // Change address for collecting fees
+ function setFee(uint256 _fee) public {
+ require(!isSealed(FEE_STATE), "ERR_SEAL");
+ require(msg.sender == owner, "ERR_AXX");
+ require(_fee < 1000000, "ERR_FEE_TOO_HIGH");
+ feePpm = _fee;
+ }
+
+ // Implements EIP173
+ function transferOwnership(address _newOwner) public returns (bool) {
+ address oldOwner;
+
+ require(msg.sender == owner);
+ oldOwner = owner;
+ owner = _newOwner;
+
+ emit OwnershipTransferred(oldOwner, owner);
+ return true;
}
function deposit(address _token, uint256 _value) public {
bool r;
bytes memory v;
- allowedToken(_token, registry);
+ mustAllowedToken(_token, registry);
(r, v) = _token.call(abi.encodeWithSignature('transferFrom(address,address,uint256)', msg.sender, this, _value));
require(r, "ERR_TOKEN");
r = abi.decode(v, (bool));
require(r, "ERR_TRANSFER");
+
+ totalSupply += _value;
}
function getFee(uint256 _value) private view returns (uint256) {
@@ -71,7 +142,7 @@ contract SwapPool {
deposit(_inToken, _value);
- (r, v) = _outToken.call(abi.encodeWithSignature('transferFrom(address,address,uint256)', this, msg.sender, netValue));
+ (r, v) = _outToken.call(abi.encodeWithSignature('transfer(address,uint256)', msg.sender, netValue));
require(r, "ERR_TOKEN");
r = abi.decode(v, (bool));
require(r, "ERR_TRANSFER");
@@ -81,11 +152,30 @@ contract SwapPool {
}
}
- function withdraw(address _token, uint256 _value) public returns (uint256) {
+ // Withdraw token to fee address
+ function withdraw(address _outToken) public returns (uint256) {
+ uint256 balance;
+ balance = fees[_outToken];
+
+ return withdraw(_outToken, balance);
}
- function allowedToken(address _token, address _registry) private {
+ function withdraw(address _outToken, uint256 _value) public returns (uint256) {
+ bool r;
+ bytes memory v;
+
+ require(feeAddress != address(0), "ERR_AXX");
+
+ (r, v) = _outToken.call(abi.encodeWithSignature('transferFrom(address,address,uint256)', this, feeAddress, _value));
+ require(r, "ERR_TOKEN");
+ r = abi.decode(v, (bool));
+ require(r, "ERR_TRANSFER");
+
+ return _value;
+ }
+
+ function mustAllowedToken(address _token, address _registry) private {
bool r;
bytes memory v;
@@ -98,4 +188,18 @@ contract SwapPool {
r = abi.decode(v, (bool));
require(r, "ERR_UNAUTH_TOKEN");
}
+
+ // Implements EIP165
+ function supportsInterface(bytes4 _sum) public pure returns (bool) {
+ if (_sum == 0x01ffc9a7) { // ERC165
+ return true;
+ }
+ if (_sum == 0x9493f8b2) { // ERC173
+ return true;
+ }
+ if (_sum == 0x0d7491f8) { // Seal
+ return true;
+ }
+ return false;
+ }
}