From b995ee05f6e32d76ab9f6163c394955fd8f66ff3 Mon Sep 17 00:00:00 2001 From: Diego Essaya Date: Thu, 22 Sep 2022 15:59:39 -0300 Subject: [PATCH] evm: add mock ERC20 contract for ISC base tokens at address 0x1075 --- packages/evm/evmtest/ISCTest.bin | 2 +- packages/vm/core/evm/evmimpl/impl.go | 12 + packages/vm/core/evm/evmimpl/iscmagic.go | 331 ++++++++++++------ packages/vm/core/evm/evmtest/evm_test.go | 104 ++++++ packages/vm/core/evm/evmtest/utils_test.go | 13 + packages/vm/core/evm/iscmagic/.gitignore | 4 + .../vm/core/evm/iscmagic/ERC20BaseTokens.abi | 1 + .../evm/iscmagic/ERC20BaseTokens.bin-runtime | 1 + .../vm/core/evm/iscmagic/ERC20BaseTokens.sol | 75 ++++ packages/vm/core/evm/iscmagic/ISC.abi | 2 +- packages/vm/core/evm/iscmagic/ISC.sol | 22 +- packages/vm/core/evm/iscmagic/ISCLib.sol | 53 +++ .../vm/core/evm/iscmagic/ISCPrivileged.abi | 1 + .../vm/core/evm/iscmagic/ISCPrivileged.sol | 14 + packages/vm/core/evm/iscmagic/embed.go | 31 +- packages/vm/core/evm/iscmagic/types.go | 7 + 16 files changed, 568 insertions(+), 105 deletions(-) create mode 100644 packages/vm/core/evm/iscmagic/.gitignore create mode 100644 packages/vm/core/evm/iscmagic/ERC20BaseTokens.abi create mode 100644 packages/vm/core/evm/iscmagic/ERC20BaseTokens.bin-runtime create mode 100644 packages/vm/core/evm/iscmagic/ERC20BaseTokens.sol create mode 100644 packages/vm/core/evm/iscmagic/ISCLib.sol create mode 100644 packages/vm/core/evm/iscmagic/ISCPrivileged.abi create mode 100644 packages/vm/core/evm/iscmagic/ISCPrivileged.sol diff --git a/packages/evm/evmtest/ISCTest.bin b/packages/evm/evmtest/ISCTest.bin index 7e6d6887bf..74289ee305 100644 --- a/packages/evm/evmtest/ISCTest.bin +++ b/packages/evm/evmtest/ISCTest.bin @@ -1 +1 @@ -608060405261107473ffffffffffffffffffffffffffffffffffffffff166360989d886040518163ffffffff1660e01b81526004016200003f9062000115565b6020604051808303816000875af11580156200005f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200008591906200017b565b6000806101000a81548161ffff021916908361ffff160217905550348015620000ad57600080fd5b50620001ad565b600082825260208201905092915050565b7f546573744572726f720000000000000000000000000000000000000000000000600082015250565b6000620000fd600983620000b4565b91506200010a82620000c5565b602082019050919050565b600060208201905081810360008301526200013081620000ee565b9050919050565b600080fd5b600061ffff82169050919050565b62000155816200013c565b81146200016157600080fd5b50565b60008151905062000175816200014a565b92915050565b60006020828403121562000194576200019362000137565b5b6000620001a48482850162000164565b91505092915050565b61312c80620001bd6000396000f3fe608060405234801561001057600080fd5b50600436106100b45760003560e01c8063564b81ef11610071578063564b81ef1461011957806357c8750e14610137578063a038a3e614610153578063a4a05e211461016f578063c36ba85614610179578063e6c75c6b14610183576100b4565b806301fc2576146100b95780631f07510c146100d5578063292aa2f3146100df57806336c34640146100fb5780633772d53f1461010557806346d116761461010f575b600080fd5b6100d360048036038101906100ce9190611553565b61019f565b005b6100dd6104bf565b005b6100f960048036038101906100f491906115e5565b61050a565b005b61010361076f565b005b61010d61081d565b005b6101176108cc565b005b610121610980565b60405161012e9190611662565b60405180910390f35b610151600480360381019061014c9190611a14565b6109f8565b005b61016d60048036038101906101689190611b2d565b610cf9565b005b610177610d67565b005b610181610ffe565b005b61019d60048036038101906101989190611b2d565b61118e565b005b6101a76111fe565b60008267ffffffffffffffff16036102415761107473ffffffffffffffffffffffffffffffffffffffff1663a714b58d336040518263ffffffff1660e01b81526004016101f49190611bb7565b600060405180830381865afa158015610211573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f8201168201806040525081019061023a9190611f57565b9050610262565b81816000019067ffffffffffffffff16908167ffffffffffffffff16815250505b61107473ffffffffffffffffffffffffffffffffffffffff1663423fa15133836040518363ffffffff1660e01b815260040161029f929190612251565b600060405180830381600087803b1580156102b957600080fd5b505af11580156102cd573d6000803e3d6000fd5b505050506102d9611229565b8160000151816000019067ffffffffffffffff16908167ffffffffffffffff168152505061030561124d565b61030d611260565b61107473ffffffffffffffffffffffffffffffffffffffff1663dbfb12ef6040518163ffffffff1660e01b8152600401610346906122de565b602060405180830381865afa158015610363573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610387919061233a565b816000019063ffffffff16908163ffffffff168152505061107473ffffffffffffffffffffffffffffffffffffffff1663dbfb12ef6040518163ffffffff1660e01b81526004016103d7906123b3565b602060405180830381865afa1580156103f4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610418919061233a565b816020019063ffffffff16908163ffffffff16815250508181604001819052506104406112b1565b61107473ffffffffffffffffffffffffffffffffffffffff16638c01f7668886600186866040518663ffffffff1660e01b8152600401610484959493929190612754565b600060405180830381600087803b15801561049e57600080fd5b505af11580156104b2573d6000803e3d6000fd5b5050505050505050505050565b60008054906101000a900461ffff166040517f057a49210000000000000000000000000000000000000000000000000000000081526004016105019190612802565b60405180910390fd5b610512611229565b610432816000019067ffffffffffffffff16908167ffffffffffffffff1681525050600067ffffffffffffffff81111561054f5761054e611381565b5b60405190808252806020026020018201604052801561058857816020015b6105756112d4565b81526020019060019003908161056d5790505b508160200181905250610599611260565b611337816020019063ffffffff16908163ffffffff168152505063d34db33f816000019063ffffffff16908163ffffffff168152505060006040518060200160405280600167ffffffffffffffff8111156105f7576105f6611381565b5b60405190808252806020026020018201604052801561063057816020015b61061d6112f4565b8152602001906001900390816106155790505b50815250905060006040518060400160405280600881526020017f2a00000000000000000000000000000000000000000000000000000000000000815250905060405180604001604052806040518060400160405280600181526020017f780000000000000000000000000000000000000000000000000000000000000081525081526020018281525082600001516000815181106106d2576106d161281d565b5b60200260200101819052508183604001819052506106ee6112b1565b61107473ffffffffffffffffffffffffffffffffffffffff166395a275a0888789600189876040518763ffffffff1660e01b81526004016107349695949392919061285b565b600060405180830381600087803b15801561074e57600080fd5b505af1158015610762573d6000803e3d6000fd5b5050505050505050505050565b600061107473ffffffffffffffffffffffffffffffffffffffff1663ca6528ce6040518163ffffffff1660e01b81526004016040805180830381865afa1580156107bd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107e19190612980565b90507fe291e1c83310126f63fb791858d0ad606ce072733612dd2547f8bbba47b420268160405161081291906129fa565b60405180910390a150565b600061107473ffffffffffffffffffffffffffffffffffffffff16635404bbf76040518163ffffffff1660e01b8152600401602060405180830381865afa15801561086c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108909190612a41565b90507f2778726dc1b9d6d2ee2628a18174907da485ba8765490e157ddf1202528ed5bc816040516108c19190612a7d565b60405180910390a150565b600061107473ffffffffffffffffffffffffffffffffffffffff1663f31317496040518163ffffffff1660e01b8152600401600060405180830381865afa15801561091b573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906109449190612af0565b90507faded0c26c8cc65771b245ec36a4a290a35b0cd003545068bcef2dcac18b8815c816040516109759190612b63565b60405180910390a150565b600061107473ffffffffffffffffffffffffffffffffffffffff1663564b81ef6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156109cf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109f39190612bb1565b905090565b60006040518060200160405280600267ffffffffffffffff811115610a2057610a1f611381565b5b604051908082528060200260200182016040528015610a5957816020015b610a466112f4565b815260200190600190039081610a3e5790505b50815250905060405180604001604052806040518060400160405280600181526020017f6100000000000000000000000000000000000000000000000000000000000000815250815260200184600001518152508160000151600081518110610ac557610ac461281d565b5b602002602001018190525060006040518060400160405280600181526020017fff00000000000000000000000000000000000000000000000000000000000000815250905060405180604001604052806040518060400160405280600181526020017f63000000000000000000000000000000000000000000000000000000000000008152508152602001828152508260000151600181518110610b6c57610b6b61281d565b5b602002602001018190525061107473ffffffffffffffffffffffffffffffffffffffff1663907327e961107473ffffffffffffffffffffffffffffffffffffffff1663dbfb12ef6040518163ffffffff1660e01b8152600401610bce906122de565b602060405180830381865afa158015610beb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c0f919061233a565b61107473ffffffffffffffffffffffffffffffffffffffff1663dbfb12ef6040518163ffffffff1660e01b8152600401610c4890612c2a565b602060405180830381865afa158015610c65573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c89919061233a565b85876040518563ffffffff1660e01b8152600401610caa9493929190612c83565b6000604051808303816000875af1158015610cc9573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190610cf29190612e97565b5050505050565b61107473ffffffffffffffffffffffffffffffffffffffff1663e6c75c6b826040518263ffffffff1660e01b8152600401610d349190612f24565b600060405180830381600087803b158015610d4e57600080fd5b505af1158015610d62573d6000803e3d6000fd5b600080fd5b60006040518060200160405280600167ffffffffffffffff811115610d8f57610d8e611381565b5b604051908082528060200260200182016040528015610dc857816020015b610db56112f4565b815260200190600190039081610dad5790505b50815250905060006040518060400160405280600881526020017f2a00000000000000000000000000000000000000000000000000000000000000815250905060405180604001604052806040518060400160405280600781526020017f636f756e746572000000000000000000000000000000000000000000000000008152508152602001828152508260000151600081518110610e6a57610e6961281d565b5b6020026020010181905250610e7d6111fe565b61107473ffffffffffffffffffffffffffffffffffffffff1663907327e961107473ffffffffffffffffffffffffffffffffffffffff1663dbfb12ef6040518163ffffffff1660e01b8152600401610ed490612f92565b602060405180830381865afa158015610ef1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f15919061233a565b61107473ffffffffffffffffffffffffffffffffffffffff1663dbfb12ef6040518163ffffffff1660e01b8152600401610f4e90612ffe565b602060405180830381865afa158015610f6b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f8f919061233a565b86856040518563ffffffff1660e01b8152600401610fb09493929190612c83565b6000604051808303816000875af1158015610fcf573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190610ff89190612e97565b50505050565b61100661124d565b61100e6111fe565b61107473ffffffffffffffffffffffffffffffffffffffff1663907327e961107473ffffffffffffffffffffffffffffffffffffffff1663dbfb12ef6040518163ffffffff1660e01b81526004016110659061306a565b602060405180830381865afa158015611082573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110a6919061233a565b61107473ffffffffffffffffffffffffffffffffffffffff1663dbfb12ef6040518163ffffffff1660e01b81526004016110df906130d6565b602060405180830381865afa1580156110fc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611120919061233a565b85856040518563ffffffff1660e01b81526004016111419493929190612c83565b6000604051808303816000875af1158015611160573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906111899190612e97565b505050565b61107473ffffffffffffffffffffffffffffffffffffffff1663e6c75c6b826040518263ffffffff1660e01b81526004016111c99190612f24565b600060405180830381600087803b1580156111e357600080fd5b505af11580156111f7573d6000803e3d6000fd5b5050505050565b6040518060600160405280600067ffffffffffffffff16815260200160608152602001606081525090565b6040518060400160405280600067ffffffffffffffff168152602001606081525090565b6040518060200160405280606081525090565b6040518060a00160405280600063ffffffff168152602001600063ffffffff16815260200161128d61124d565b815260200161129a6111fe565b8152602001600067ffffffffffffffff1681525090565b6040518060400160405280600060070b81526020016112ce61130e565b81525090565b60405180604001604052806112e7611331565b8152602001600081525090565b604051806040016040528060608152602001606081525090565b6040518060400160405280600060070b815260200161132b611344565b81525090565b6040518060200160405280606081525090565b6040518060200160405280606081525090565b6000604051905090565b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6113b982611370565b810181811067ffffffffffffffff821117156113d8576113d7611381565b5b80604052505050565b60006113eb611357565b90506113f782826113b0565b919050565b600080fd5b600080fd5b600080fd5b600067ffffffffffffffff82111561142657611425611381565b5b61142f82611370565b9050602081019050919050565b82818337600083830152505050565b600061145e6114598461140b565b6113e1565b90508281526020810184848401111561147a57611479611406565b5b61148584828561143c565b509392505050565b600082601f8301126114a2576114a1611401565b5b81356114b284826020860161144b565b91505092915050565b6000602082840312156114d1576114d061136b565b5b6114db60206113e1565b9050600082013567ffffffffffffffff8111156114fb576114fa6113fc565b5b6115078482850161148d565b60008301525092915050565b600067ffffffffffffffff82169050919050565b61153081611513565b811461153b57600080fd5b50565b60008135905061154d81611527565b92915050565b6000806040838503121561156a57611569611361565b5b600083013567ffffffffffffffff81111561158857611587611366565b5b611594858286016114bb565b92505060206115a58582860161153e565b9150509250929050565b6000819050919050565b6115c2816115af565b81146115cd57600080fd5b50565b6000813590506115df816115b9565b92915050565b600080604083850312156115fc576115fb611361565b5b600083013567ffffffffffffffff81111561161a57611619611366565b5b611626858286016114bb565b9250506020611637858286016115d0565b9150509250929050565b600061164c826115af565b9050919050565b61165c81611641565b82525050565b60006020820190506116776000830184611653565b92915050565b6000602082840312156116935761169261136b565b5b61169d60206113e1565b9050600082013567ffffffffffffffff8111156116bd576116bc6113fc565b5b6116c98482850161148d565b60008301525092915050565b600067ffffffffffffffff8211156116f0576116ef611381565b5b602082029050602081019050919050565b600080fd5b60006020828403121561171c5761171b61136b565b5b61172660206113e1565b9050600082013567ffffffffffffffff811115611746576117456113fc565b5b6117528482850161148d565b60008301525092915050565b6000819050919050565b6117718161175e565b811461177c57600080fd5b50565b60008135905061178e81611768565b92915050565b6000604082840312156117aa576117a961136b565b5b6117b460406113e1565b9050600082013567ffffffffffffffff8111156117d4576117d36113fc565b5b6117e084828501611706565b60008301525060206117f48482850161177f565b60208301525092915050565b600061181361180e846116d5565b6113e1565b9050808382526020820190506020840283018581111561183657611835611701565b5b835b8181101561187d57803567ffffffffffffffff81111561185b5761185a611401565b5b8086016118688982611794565b85526020850194505050602081019050611838565b5050509392505050565b600082601f83011261189c5761189b611401565b5b81356118ac848260208601611800565b91505092915050565b600067ffffffffffffffff8211156118d0576118cf611381565b5b602082029050602081019050919050565b60006118f46118ef846118b5565b6113e1565b9050808382526020820190506020840283018581111561191757611916611701565b5b835b81811015611940578061192c88826115d0565b845260208401935050602081019050611919565b5050509392505050565b600082601f83011261195f5761195e611401565b5b813561196f8482602086016118e1565b91505092915050565b60006060828403121561198e5761198d61136b565b5b61199860606113e1565b905060006119a88482850161153e565b600083015250602082013567ffffffffffffffff8111156119cc576119cb6113fc565b5b6119d884828501611887565b602083015250604082013567ffffffffffffffff8111156119fc576119fb6113fc565b5b611a088482850161194a565b60408301525092915050565b60008060408385031215611a2b57611a2a611361565b5b600083013567ffffffffffffffff811115611a4957611a48611366565b5b611a558582860161167d565b925050602083013567ffffffffffffffff811115611a7657611a75611366565b5b611a8285828601611978565b9150509250929050565b600067ffffffffffffffff821115611aa757611aa6611381565b5b611ab082611370565b9050602081019050919050565b6000611ad0611acb84611a8c565b6113e1565b905082815260208101848484011115611aec57611aeb611406565b5b611af784828561143c565b509392505050565b600082601f830112611b1457611b13611401565b5b8135611b24848260208601611abd565b91505092915050565b600060208284031215611b4357611b42611361565b5b600082013567ffffffffffffffff811115611b6157611b60611366565b5b611b6d84828501611aff565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000611ba182611b76565b9050919050565b611bb181611b96565b82525050565b6000602082019050611bcc6000830184611ba8565b92915050565b600081519050611be181611527565b92915050565b60005b83811015611c05578082015181840152602081019050611bea565b60008484015250505050565b6000611c24611c1f8461140b565b6113e1565b905082815260208101848484011115611c4057611c3f611406565b5b611c4b848285611be7565b509392505050565b600082601f830112611c6857611c67611401565b5b8151611c78848260208601611c11565b91505092915050565b600060208284031215611c9757611c9661136b565b5b611ca160206113e1565b9050600082015167ffffffffffffffff811115611cc157611cc06113fc565b5b611ccd84828501611c53565b60008301525092915050565b600081519050611ce881611768565b92915050565b600060408284031215611d0457611d0361136b565b5b611d0e60406113e1565b9050600082015167ffffffffffffffff811115611d2e57611d2d6113fc565b5b611d3a84828501611c81565b6000830152506020611d4e84828501611cd9565b60208301525092915050565b6000611d6d611d68846116d5565b6113e1565b90508083825260208201905060208402830185811115611d9057611d8f611701565b5b835b81811015611dd757805167ffffffffffffffff811115611db557611db4611401565b5b808601611dc28982611cee565b85526020850194505050602081019050611d92565b5050509392505050565b600082601f830112611df657611df5611401565b5b8151611e06848260208601611d5a565b91505092915050565b600081519050611e1e816115b9565b92915050565b6000611e37611e32846118b5565b6113e1565b90508083825260208201905060208402830185811115611e5a57611e59611701565b5b835b81811015611e835780611e6f8882611e0f565b845260208401935050602081019050611e5c565b5050509392505050565b600082601f830112611ea257611ea1611401565b5b8151611eb2848260208601611e24565b91505092915050565b600060608284031215611ed157611ed061136b565b5b611edb60606113e1565b90506000611eeb84828501611bd2565b600083015250602082015167ffffffffffffffff811115611f0f57611f0e6113fc565b5b611f1b84828501611de1565b602083015250604082015167ffffffffffffffff811115611f3f57611f3e6113fc565b5b611f4b84828501611e8d565b60408301525092915050565b600060208284031215611f6d57611f6c611361565b5b600082015167ffffffffffffffff811115611f8b57611f8a611366565b5b611f9784828501611ebb565b91505092915050565b611fa981611513565b82525050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b600081519050919050565b600082825260208201905092915050565b600061200282611fdb565b61200c8185611fe6565b935061201c818560208601611be7565b61202581611370565b840191505092915050565b6000602083016000830151848203600086015261204d8282611ff7565b9150508091505092915050565b6120638161175e565b82525050565b600060408301600083015184820360008601526120868282612030565b915050602083015161209b602086018261205a565b508091505092915050565b60006120b28383612069565b905092915050565b6000602082019050919050565b60006120d282611faf565b6120dc8185611fba565b9350836020820285016120ee85611fcb565b8060005b8581101561212a578484038952815161210b85826120a6565b9450612116836120ba565b925060208a019950506001810190506120f2565b50829750879550505050505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b61217181611641565b82525050565b60006121838383612168565b60208301905092915050565b6000602082019050919050565b60006121a78261213c565b6121b18185612147565b93506121bc83612158565b8060005b838110156121ed5781516121d48882612177565b97506121df8361218f565b9250506001810190506121c0565b5085935050505092915050565b60006060830160008301516122126000860182611fa0565b506020830151848203602086015261222a82826120c7565b91505060408301518482036040860152612244828261219c565b9150508091505092915050565b60006040820190506122666000830185611ba8565b818103602083015261227881846121fa565b90509392505050565b600082825260208201905092915050565b7f6163636f756e7473000000000000000000000000000000000000000000000000600082015250565b60006122c8600883612281565b91506122d382612292565b602082019050919050565b600060208201905081810360008301526122f7816122bb565b9050919050565b600063ffffffff82169050919050565b612317816122fe565b811461232257600080fd5b50565b6000815190506123348161230e565b92915050565b6000602082840312156123505761234f611361565b5b600061235e84828501612325565b91505092915050565b7f6465706f73697400000000000000000000000000000000000000000000000000600082015250565b600061239d600783612281565b91506123a882612367565b602082019050919050565b600060208201905081810360008301526123cc81612390565b9050919050565b600060208301600083015184820360008601526123f08282611ff7565b9150508091505092915050565b60006040830160008301516124156000860182611fa0565b506020830151848203602086015261242d82826120c7565b9150508091505092915050565b60008115159050919050565b61244f8161243a565b82525050565b6000819050919050565b600061247a612475612470846122fe565b612455565b6122fe565b9050919050565b61248a8161245f565b82525050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b600060408301600083015184820360008601526124d98282611ff7565b915050602083015184820360208601526124f38282611ff7565b9150508091505092915050565b600061250c83836124bc565b905092915050565b6000602082019050919050565b600061252c82612490565b612536818561249b565b935083602082028501612548856124ac565b8060005b8581101561258457848403895281516125658582612500565b945061257083612514565b925060208a0199505060018101905061254c565b50829750879550505050505092915050565b600060208301600083015184820360008601526125b38282612521565b9150508091505092915050565b60006060830160008301516125d86000860182611fa0565b50602083015184820360208601526125f082826120c7565b9150506040830151848203604086015261260a828261219c565b9150508091505092915050565b600060a08301600083015161262f6000860182612481565b5060208301516126426020860182612481565b506040830151848203604086015261265a8282612596565b9150506060830151848203606086015261267482826125c0565b91505060808301516126896080860182611fa0565b508091505092915050565b60008160070b9050919050565b6126aa81612694565b82525050565b600060208301600083015184820360008601526126cd8282611ff7565b9150508091505092915050565b60006040830160008301516126f260008601826126a1565b506020830151848203602086015261270a82826126b0565b9150508091505092915050565b600060408301600083015161272f60008601826126a1565b506020830151848203602086015261274782826126da565b9150508091505092915050565b600060a082019050818103600083015261276e81886123d3565b9050818103602083015261278281876123fd565b90506127916040830186612446565b81810360608301526127a38185612617565b905081810360808301526127b78184612717565b90509695505050505050565b600061ffff82169050919050565b60006127ec6127e76127e2846127c3565b612455565b6127c3565b9050919050565b6127fc816127d1565b82525050565b600060208201905061281760008301846127f3565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b61285581611641565b82525050565b600060c082019050818103600083015261287581896123d3565b9050818103602083015261288981886123fd565b9050612898604083018761284c565b6128a56060830186612446565b81810360808301526128b78185612617565b905081810360a08301526128cb8184612717565b9050979650505050505050565b6128e1816115af565b81146128ec57600080fd5b50565b6000815190506128fe816128d8565b92915050565b61290d816127c3565b811461291857600080fd5b50565b60008151905061292a81612904565b92915050565b6000604082840312156129465761294561136b565b5b61295060406113e1565b90506000612960848285016128ef565b60008301525060206129748482850161291b565b60208301525092915050565b60006040828403121561299657612995611361565b5b60006129a484828501612930565b91505092915050565b6129b681611641565b82525050565b6129c5816127c3565b82525050565b6040820160008201516129e160008501826129ad565b5060208201516129f460208501826129bc565b50505050565b6000604082019050612a0f60008301846129cb565b92915050565b612a1e816115af565b8114612a2957600080fd5b50565b600081519050612a3b81612a15565b92915050565b600060208284031215612a5757612a56611361565b5b6000612a6584828501612a2c565b91505092915050565b612a77816115af565b82525050565b6000602082019050612a926000830184612a6e565b92915050565b600060208284031215612aae57612aad61136b565b5b612ab860206113e1565b9050600082015167ffffffffffffffff811115612ad857612ad76113fc565b5b612ae484828501611c53565b60008301525092915050565b600060208284031215612b0657612b05611361565b5b600082015167ffffffffffffffff811115612b2457612b23611366565b5b612b3084828501612a98565b91505092915050565b60006020830160008301518482036000860152612b568282611ff7565b9150508091505092915050565b60006020820190508181036000830152612b7d8184612b39565b905092915050565b612b8e816115af565b8114612b9957600080fd5b50565b600081519050612bab81612b85565b92915050565b600060208284031215612bc757612bc6611361565b5b6000612bd584828501612b9c565b91505092915050565b7f7472616e73666572416c6c6f77616e6365546f00000000000000000000000000600082015250565b6000612c14601383612281565b9150612c1f82612bde565b602082019050919050565b60006020820190508181036000830152612c4381612c07565b9050919050565b612c538161245f565b82525050565b60006020830160008301518482036000860152612c768282612521565b9150508091505092915050565b6000608082019050612c986000830187612c4a565b612ca56020830186612c4a565b8181036040830152612cb78185612c59565b90508181036060830152612ccb81846121fa565b905095945050505050565b600067ffffffffffffffff821115612cf157612cf0611381565b5b602082029050602081019050919050565b600060408284031215612d1857612d1761136b565b5b612d2260406113e1565b9050600082015167ffffffffffffffff811115612d4257612d416113fc565b5b612d4e84828501611c53565b600083015250602082015167ffffffffffffffff811115612d7257612d716113fc565b5b612d7e84828501611c53565b60208301525092915050565b6000612d9d612d9884612cd6565b6113e1565b90508083825260208201905060208402830185811115612dc057612dbf611701565b5b835b81811015612e0757805167ffffffffffffffff811115612de557612de4611401565b5b808601612df28982612d02565b85526020850194505050602081019050612dc2565b5050509392505050565b600082601f830112612e2657612e25611401565b5b8151612e36848260208601612d8a565b91505092915050565b600060208284031215612e5557612e5461136b565b5b612e5f60206113e1565b9050600082015167ffffffffffffffff811115612e7f57612e7e6113fc565b5b612e8b84828501612e11565b60008301525092915050565b600060208284031215612ead57612eac611361565b5b600082015167ffffffffffffffff811115612ecb57612eca611366565b5b612ed784828501612e3f565b91505092915050565b600081519050919050565b6000612ef682612ee0565b612f008185612281565b9350612f10818560208601611be7565b612f1981611370565b840191505092915050565b60006020820190508181036000830152612f3e8184612eeb565b905092915050565b7f696e63636f756e74657200000000000000000000000000000000000000000000600082015250565b6000612f7c600a83612281565b9150612f8782612f46565b602082019050919050565b60006020820190508181036000830152612fab81612f6f565b9050919050565b7f696e63436f756e74657200000000000000000000000000000000000000000000600082015250565b6000612fe8600a83612281565b9150612ff382612fb2565b602082019050919050565b6000602082019050818103600083015261301781612fdb565b9050919050565b7f676f7665726e616e636500000000000000000000000000000000000000000000600082015250565b6000613054600a83612281565b915061305f8261301e565b602082019050919050565b6000602082019050818103600083015261308381613047565b9050919050565b7f636c61696d436861696e4f776e65727368690000000000000000000000000000600082015250565b60006130c0601283612281565b91506130cb8261308a565b602082019050919050565b600060208201905081810360008301526130ef816130b3565b905091905056fea264697066735822122071180481a92a54c3657c5a6c1d05ed3dda5681423f913b5159aeb1f9c2347b1164736f6c63430008100033 \ No newline at end of file +608060405261107473ffffffffffffffffffffffffffffffffffffffff166360989d886040518163ffffffff1660e01b81526004016200003f9062000115565b6020604051808303816000875af11580156200005f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200008591906200017b565b6000806101000a81548161ffff021916908361ffff160217905550348015620000ad57600080fd5b50620001ad565b600082825260208201905092915050565b7f546573744572726f720000000000000000000000000000000000000000000000600082015250565b6000620000fd600983620000b4565b91506200010a82620000c5565b602082019050919050565b600060208201905081810360008301526200013081620000ee565b9050919050565b600080fd5b600061ffff82169050919050565b62000155816200013c565b81146200016157600080fd5b50565b60008151905062000175816200014a565b92915050565b60006020828403121562000194576200019362000137565b5b6000620001a48482850162000164565b91505092915050565b61312c80620001bd6000396000f3fe608060405234801561001057600080fd5b50600436106100b45760003560e01c8063564b81ef11610071578063564b81ef1461011957806357c8750e14610137578063a038a3e614610153578063a4a05e211461016f578063c36ba85614610179578063e6c75c6b14610183576100b4565b806301fc2576146100b95780631f07510c146100d5578063292aa2f3146100df57806336c34640146100fb5780633772d53f1461010557806346d116761461010f575b600080fd5b6100d360048036038101906100ce9190611553565b61019f565b005b6100dd6104bf565b005b6100f960048036038101906100f491906115e5565b61050a565b005b61010361076f565b005b61010d61081d565b005b6101176108cc565b005b610121610980565b60405161012e9190611662565b60405180910390f35b610151600480360381019061014c9190611a14565b6109f8565b005b61016d60048036038101906101689190611b2d565b610cf9565b005b610177610d67565b005b610181610ffe565b005b61019d60048036038101906101989190611b2d565b61118e565b005b6101a76111fe565b60008267ffffffffffffffff16036102415761107473ffffffffffffffffffffffffffffffffffffffff1663a714b58d336040518263ffffffff1660e01b81526004016101f49190611bb7565b600060405180830381865afa158015610211573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f8201168201806040525081019061023a9190611f57565b9050610262565b81816000019067ffffffffffffffff16908167ffffffffffffffff16815250505b61107473ffffffffffffffffffffffffffffffffffffffff1663423fa15133836040518363ffffffff1660e01b815260040161029f929190612251565b600060405180830381600087803b1580156102b957600080fd5b505af11580156102cd573d6000803e3d6000fd5b505050506102d9611229565b8160000151816000019067ffffffffffffffff16908167ffffffffffffffff168152505061030561124d565b61030d611260565b61107473ffffffffffffffffffffffffffffffffffffffff1663dbfb12ef6040518163ffffffff1660e01b8152600401610346906122de565b602060405180830381865afa158015610363573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610387919061233a565b816000019063ffffffff16908163ffffffff168152505061107473ffffffffffffffffffffffffffffffffffffffff1663dbfb12ef6040518163ffffffff1660e01b81526004016103d7906123b3565b602060405180830381865afa1580156103f4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610418919061233a565b816020019063ffffffff16908163ffffffff16815250508181604001819052506104406112b1565b61107473ffffffffffffffffffffffffffffffffffffffff16638c01f7668886600186866040518663ffffffff1660e01b8152600401610484959493929190612754565b600060405180830381600087803b15801561049e57600080fd5b505af11580156104b2573d6000803e3d6000fd5b5050505050505050505050565b60008054906101000a900461ffff166040517f057a49210000000000000000000000000000000000000000000000000000000081526004016105019190612802565b60405180910390fd5b610512611229565b610432816000019067ffffffffffffffff16908167ffffffffffffffff1681525050600067ffffffffffffffff81111561054f5761054e611381565b5b60405190808252806020026020018201604052801561058857816020015b6105756112d4565b81526020019060019003908161056d5790505b508160200181905250610599611260565b611337816020019063ffffffff16908163ffffffff168152505063d34db33f816000019063ffffffff16908163ffffffff168152505060006040518060200160405280600167ffffffffffffffff8111156105f7576105f6611381565b5b60405190808252806020026020018201604052801561063057816020015b61061d6112f4565b8152602001906001900390816106155790505b50815250905060006040518060400160405280600881526020017f2a00000000000000000000000000000000000000000000000000000000000000815250905060405180604001604052806040518060400160405280600181526020017f780000000000000000000000000000000000000000000000000000000000000081525081526020018281525082600001516000815181106106d2576106d161281d565b5b60200260200101819052508183604001819052506106ee6112b1565b61107473ffffffffffffffffffffffffffffffffffffffff166395a275a0888789600189876040518763ffffffff1660e01b81526004016107349695949392919061285b565b600060405180830381600087803b15801561074e57600080fd5b505af1158015610762573d6000803e3d6000fd5b5050505050505050505050565b600061107473ffffffffffffffffffffffffffffffffffffffff1663ca6528ce6040518163ffffffff1660e01b81526004016040805180830381865afa1580156107bd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107e19190612980565b90507fe291e1c83310126f63fb791858d0ad606ce072733612dd2547f8bbba47b420268160405161081291906129fa565b60405180910390a150565b600061107473ffffffffffffffffffffffffffffffffffffffff16635404bbf76040518163ffffffff1660e01b8152600401602060405180830381865afa15801561086c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108909190612a41565b90507f2778726dc1b9d6d2ee2628a18174907da485ba8765490e157ddf1202528ed5bc816040516108c19190612a7d565b60405180910390a150565b600061107473ffffffffffffffffffffffffffffffffffffffff1663f31317496040518163ffffffff1660e01b8152600401600060405180830381865afa15801561091b573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906109449190612af0565b90507faded0c26c8cc65771b245ec36a4a290a35b0cd003545068bcef2dcac18b8815c816040516109759190612b63565b60405180910390a150565b600061107473ffffffffffffffffffffffffffffffffffffffff1663564b81ef6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156109cf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109f39190612bb1565b905090565b60006040518060200160405280600267ffffffffffffffff811115610a2057610a1f611381565b5b604051908082528060200260200182016040528015610a5957816020015b610a466112f4565b815260200190600190039081610a3e5790505b50815250905060405180604001604052806040518060400160405280600181526020017f6100000000000000000000000000000000000000000000000000000000000000815250815260200184600001518152508160000151600081518110610ac557610ac461281d565b5b602002602001018190525060006040518060400160405280600181526020017fff00000000000000000000000000000000000000000000000000000000000000815250905060405180604001604052806040518060400160405280600181526020017f63000000000000000000000000000000000000000000000000000000000000008152508152602001828152508260000151600181518110610b6c57610b6b61281d565b5b602002602001018190525061107473ffffffffffffffffffffffffffffffffffffffff1663907327e961107473ffffffffffffffffffffffffffffffffffffffff1663dbfb12ef6040518163ffffffff1660e01b8152600401610bce906122de565b602060405180830381865afa158015610beb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c0f919061233a565b61107473ffffffffffffffffffffffffffffffffffffffff1663dbfb12ef6040518163ffffffff1660e01b8152600401610c4890612c2a565b602060405180830381865afa158015610c65573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c89919061233a565b85876040518563ffffffff1660e01b8152600401610caa9493929190612c83565b6000604051808303816000875af1158015610cc9573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190610cf29190612e97565b5050505050565b61107473ffffffffffffffffffffffffffffffffffffffff1663e6c75c6b826040518263ffffffff1660e01b8152600401610d349190612f24565b600060405180830381600087803b158015610d4e57600080fd5b505af1158015610d62573d6000803e3d6000fd5b600080fd5b60006040518060200160405280600167ffffffffffffffff811115610d8f57610d8e611381565b5b604051908082528060200260200182016040528015610dc857816020015b610db56112f4565b815260200190600190039081610dad5790505b50815250905060006040518060400160405280600881526020017f2a00000000000000000000000000000000000000000000000000000000000000815250905060405180604001604052806040518060400160405280600781526020017f636f756e746572000000000000000000000000000000000000000000000000008152508152602001828152508260000151600081518110610e6a57610e6961281d565b5b6020026020010181905250610e7d6111fe565b61107473ffffffffffffffffffffffffffffffffffffffff1663907327e961107473ffffffffffffffffffffffffffffffffffffffff1663dbfb12ef6040518163ffffffff1660e01b8152600401610ed490612f92565b602060405180830381865afa158015610ef1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f15919061233a565b61107473ffffffffffffffffffffffffffffffffffffffff1663dbfb12ef6040518163ffffffff1660e01b8152600401610f4e90612ffe565b602060405180830381865afa158015610f6b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f8f919061233a565b86856040518563ffffffff1660e01b8152600401610fb09493929190612c83565b6000604051808303816000875af1158015610fcf573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190610ff89190612e97565b50505050565b61100661124d565b61100e6111fe565b61107473ffffffffffffffffffffffffffffffffffffffff1663907327e961107473ffffffffffffffffffffffffffffffffffffffff1663dbfb12ef6040518163ffffffff1660e01b81526004016110659061306a565b602060405180830381865afa158015611082573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110a6919061233a565b61107473ffffffffffffffffffffffffffffffffffffffff1663dbfb12ef6040518163ffffffff1660e01b81526004016110df906130d6565b602060405180830381865afa1580156110fc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611120919061233a565b85856040518563ffffffff1660e01b81526004016111419493929190612c83565b6000604051808303816000875af1158015611160573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906111899190612e97565b505050565b61107473ffffffffffffffffffffffffffffffffffffffff1663e6c75c6b826040518263ffffffff1660e01b81526004016111c99190612f24565b600060405180830381600087803b1580156111e357600080fd5b505af11580156111f7573d6000803e3d6000fd5b5050505050565b6040518060600160405280600067ffffffffffffffff16815260200160608152602001606081525090565b6040518060400160405280600067ffffffffffffffff168152602001606081525090565b6040518060200160405280606081525090565b6040518060a00160405280600063ffffffff168152602001600063ffffffff16815260200161128d61124d565b815260200161129a6111fe565b8152602001600067ffffffffffffffff1681525090565b6040518060400160405280600060070b81526020016112ce61130e565b81525090565b60405180604001604052806112e7611331565b8152602001600081525090565b604051806040016040528060608152602001606081525090565b6040518060400160405280600060070b815260200161132b611344565b81525090565b6040518060200160405280606081525090565b6040518060200160405280606081525090565b6000604051905090565b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6113b982611370565b810181811067ffffffffffffffff821117156113d8576113d7611381565b5b80604052505050565b60006113eb611357565b90506113f782826113b0565b919050565b600080fd5b600080fd5b600080fd5b600067ffffffffffffffff82111561142657611425611381565b5b61142f82611370565b9050602081019050919050565b82818337600083830152505050565b600061145e6114598461140b565b6113e1565b90508281526020810184848401111561147a57611479611406565b5b61148584828561143c565b509392505050565b600082601f8301126114a2576114a1611401565b5b81356114b284826020860161144b565b91505092915050565b6000602082840312156114d1576114d061136b565b5b6114db60206113e1565b9050600082013567ffffffffffffffff8111156114fb576114fa6113fc565b5b6115078482850161148d565b60008301525092915050565b600067ffffffffffffffff82169050919050565b61153081611513565b811461153b57600080fd5b50565b60008135905061154d81611527565b92915050565b6000806040838503121561156a57611569611361565b5b600083013567ffffffffffffffff81111561158857611587611366565b5b611594858286016114bb565b92505060206115a58582860161153e565b9150509250929050565b6000819050919050565b6115c2816115af565b81146115cd57600080fd5b50565b6000813590506115df816115b9565b92915050565b600080604083850312156115fc576115fb611361565b5b600083013567ffffffffffffffff81111561161a57611619611366565b5b611626858286016114bb565b9250506020611637858286016115d0565b9150509250929050565b600061164c826115af565b9050919050565b61165c81611641565b82525050565b60006020820190506116776000830184611653565b92915050565b6000602082840312156116935761169261136b565b5b61169d60206113e1565b9050600082013567ffffffffffffffff8111156116bd576116bc6113fc565b5b6116c98482850161148d565b60008301525092915050565b600067ffffffffffffffff8211156116f0576116ef611381565b5b602082029050602081019050919050565b600080fd5b60006020828403121561171c5761171b61136b565b5b61172660206113e1565b9050600082013567ffffffffffffffff811115611746576117456113fc565b5b6117528482850161148d565b60008301525092915050565b6000819050919050565b6117718161175e565b811461177c57600080fd5b50565b60008135905061178e81611768565b92915050565b6000604082840312156117aa576117a961136b565b5b6117b460406113e1565b9050600082013567ffffffffffffffff8111156117d4576117d36113fc565b5b6117e084828501611706565b60008301525060206117f48482850161177f565b60208301525092915050565b600061181361180e846116d5565b6113e1565b9050808382526020820190506020840283018581111561183657611835611701565b5b835b8181101561187d57803567ffffffffffffffff81111561185b5761185a611401565b5b8086016118688982611794565b85526020850194505050602081019050611838565b5050509392505050565b600082601f83011261189c5761189b611401565b5b81356118ac848260208601611800565b91505092915050565b600067ffffffffffffffff8211156118d0576118cf611381565b5b602082029050602081019050919050565b60006118f46118ef846118b5565b6113e1565b9050808382526020820190506020840283018581111561191757611916611701565b5b835b81811015611940578061192c88826115d0565b845260208401935050602081019050611919565b5050509392505050565b600082601f83011261195f5761195e611401565b5b813561196f8482602086016118e1565b91505092915050565b60006060828403121561198e5761198d61136b565b5b61199860606113e1565b905060006119a88482850161153e565b600083015250602082013567ffffffffffffffff8111156119cc576119cb6113fc565b5b6119d884828501611887565b602083015250604082013567ffffffffffffffff8111156119fc576119fb6113fc565b5b611a088482850161194a565b60408301525092915050565b60008060408385031215611a2b57611a2a611361565b5b600083013567ffffffffffffffff811115611a4957611a48611366565b5b611a558582860161167d565b925050602083013567ffffffffffffffff811115611a7657611a75611366565b5b611a8285828601611978565b9150509250929050565b600067ffffffffffffffff821115611aa757611aa6611381565b5b611ab082611370565b9050602081019050919050565b6000611ad0611acb84611a8c565b6113e1565b905082815260208101848484011115611aec57611aeb611406565b5b611af784828561143c565b509392505050565b600082601f830112611b1457611b13611401565b5b8135611b24848260208601611abd565b91505092915050565b600060208284031215611b4357611b42611361565b5b600082013567ffffffffffffffff811115611b6157611b60611366565b5b611b6d84828501611aff565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000611ba182611b76565b9050919050565b611bb181611b96565b82525050565b6000602082019050611bcc6000830184611ba8565b92915050565b600081519050611be181611527565b92915050565b60005b83811015611c05578082015181840152602081019050611bea565b60008484015250505050565b6000611c24611c1f8461140b565b6113e1565b905082815260208101848484011115611c4057611c3f611406565b5b611c4b848285611be7565b509392505050565b600082601f830112611c6857611c67611401565b5b8151611c78848260208601611c11565b91505092915050565b600060208284031215611c9757611c9661136b565b5b611ca160206113e1565b9050600082015167ffffffffffffffff811115611cc157611cc06113fc565b5b611ccd84828501611c53565b60008301525092915050565b600081519050611ce881611768565b92915050565b600060408284031215611d0457611d0361136b565b5b611d0e60406113e1565b9050600082015167ffffffffffffffff811115611d2e57611d2d6113fc565b5b611d3a84828501611c81565b6000830152506020611d4e84828501611cd9565b60208301525092915050565b6000611d6d611d68846116d5565b6113e1565b90508083825260208201905060208402830185811115611d9057611d8f611701565b5b835b81811015611dd757805167ffffffffffffffff811115611db557611db4611401565b5b808601611dc28982611cee565b85526020850194505050602081019050611d92565b5050509392505050565b600082601f830112611df657611df5611401565b5b8151611e06848260208601611d5a565b91505092915050565b600081519050611e1e816115b9565b92915050565b6000611e37611e32846118b5565b6113e1565b90508083825260208201905060208402830185811115611e5a57611e59611701565b5b835b81811015611e835780611e6f8882611e0f565b845260208401935050602081019050611e5c565b5050509392505050565b600082601f830112611ea257611ea1611401565b5b8151611eb2848260208601611e24565b91505092915050565b600060608284031215611ed157611ed061136b565b5b611edb60606113e1565b90506000611eeb84828501611bd2565b600083015250602082015167ffffffffffffffff811115611f0f57611f0e6113fc565b5b611f1b84828501611de1565b602083015250604082015167ffffffffffffffff811115611f3f57611f3e6113fc565b5b611f4b84828501611e8d565b60408301525092915050565b600060208284031215611f6d57611f6c611361565b5b600082015167ffffffffffffffff811115611f8b57611f8a611366565b5b611f9784828501611ebb565b91505092915050565b611fa981611513565b82525050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b600081519050919050565b600082825260208201905092915050565b600061200282611fdb565b61200c8185611fe6565b935061201c818560208601611be7565b61202581611370565b840191505092915050565b6000602083016000830151848203600086015261204d8282611ff7565b9150508091505092915050565b6120638161175e565b82525050565b600060408301600083015184820360008601526120868282612030565b915050602083015161209b602086018261205a565b508091505092915050565b60006120b28383612069565b905092915050565b6000602082019050919050565b60006120d282611faf565b6120dc8185611fba565b9350836020820285016120ee85611fcb565b8060005b8581101561212a578484038952815161210b85826120a6565b9450612116836120ba565b925060208a019950506001810190506120f2565b50829750879550505050505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b61217181611641565b82525050565b60006121838383612168565b60208301905092915050565b6000602082019050919050565b60006121a78261213c565b6121b18185612147565b93506121bc83612158565b8060005b838110156121ed5781516121d48882612177565b97506121df8361218f565b9250506001810190506121c0565b5085935050505092915050565b60006060830160008301516122126000860182611fa0565b506020830151848203602086015261222a82826120c7565b91505060408301518482036040860152612244828261219c565b9150508091505092915050565b60006040820190506122666000830185611ba8565b818103602083015261227881846121fa565b90509392505050565b600082825260208201905092915050565b7f6163636f756e7473000000000000000000000000000000000000000000000000600082015250565b60006122c8600883612281565b91506122d382612292565b602082019050919050565b600060208201905081810360008301526122f7816122bb565b9050919050565b600063ffffffff82169050919050565b612317816122fe565b811461232257600080fd5b50565b6000815190506123348161230e565b92915050565b6000602082840312156123505761234f611361565b5b600061235e84828501612325565b91505092915050565b7f6465706f73697400000000000000000000000000000000000000000000000000600082015250565b600061239d600783612281565b91506123a882612367565b602082019050919050565b600060208201905081810360008301526123cc81612390565b9050919050565b600060208301600083015184820360008601526123f08282611ff7565b9150508091505092915050565b60006040830160008301516124156000860182611fa0565b506020830151848203602086015261242d82826120c7565b9150508091505092915050565b60008115159050919050565b61244f8161243a565b82525050565b6000819050919050565b600061247a612475612470846122fe565b612455565b6122fe565b9050919050565b61248a8161245f565b82525050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b600060408301600083015184820360008601526124d98282611ff7565b915050602083015184820360208601526124f38282611ff7565b9150508091505092915050565b600061250c83836124bc565b905092915050565b6000602082019050919050565b600061252c82612490565b612536818561249b565b935083602082028501612548856124ac565b8060005b8581101561258457848403895281516125658582612500565b945061257083612514565b925060208a0199505060018101905061254c565b50829750879550505050505092915050565b600060208301600083015184820360008601526125b38282612521565b9150508091505092915050565b60006060830160008301516125d86000860182611fa0565b50602083015184820360208601526125f082826120c7565b9150506040830151848203604086015261260a828261219c565b9150508091505092915050565b600060a08301600083015161262f6000860182612481565b5060208301516126426020860182612481565b506040830151848203604086015261265a8282612596565b9150506060830151848203606086015261267482826125c0565b91505060808301516126896080860182611fa0565b508091505092915050565b60008160070b9050919050565b6126aa81612694565b82525050565b600060208301600083015184820360008601526126cd8282611ff7565b9150508091505092915050565b60006040830160008301516126f260008601826126a1565b506020830151848203602086015261270a82826126b0565b9150508091505092915050565b600060408301600083015161272f60008601826126a1565b506020830151848203602086015261274782826126da565b9150508091505092915050565b600060a082019050818103600083015261276e81886123d3565b9050818103602083015261278281876123fd565b90506127916040830186612446565b81810360608301526127a38185612617565b905081810360808301526127b78184612717565b90509695505050505050565b600061ffff82169050919050565b60006127ec6127e76127e2846127c3565b612455565b6127c3565b9050919050565b6127fc816127d1565b82525050565b600060208201905061281760008301846127f3565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b61285581611641565b82525050565b600060c082019050818103600083015261287581896123d3565b9050818103602083015261288981886123fd565b9050612898604083018761284c565b6128a56060830186612446565b81810360808301526128b78185612617565b905081810360a08301526128cb8184612717565b9050979650505050505050565b6128e1816115af565b81146128ec57600080fd5b50565b6000815190506128fe816128d8565b92915050565b61290d816127c3565b811461291857600080fd5b50565b60008151905061292a81612904565b92915050565b6000604082840312156129465761294561136b565b5b61295060406113e1565b90506000612960848285016128ef565b60008301525060206129748482850161291b565b60208301525092915050565b60006040828403121561299657612995611361565b5b60006129a484828501612930565b91505092915050565b6129b681611641565b82525050565b6129c5816127c3565b82525050565b6040820160008201516129e160008501826129ad565b5060208201516129f460208501826129bc565b50505050565b6000604082019050612a0f60008301846129cb565b92915050565b612a1e816115af565b8114612a2957600080fd5b50565b600081519050612a3b81612a15565b92915050565b600060208284031215612a5757612a56611361565b5b6000612a6584828501612a2c565b91505092915050565b612a77816115af565b82525050565b6000602082019050612a926000830184612a6e565b92915050565b600060208284031215612aae57612aad61136b565b5b612ab860206113e1565b9050600082015167ffffffffffffffff811115612ad857612ad76113fc565b5b612ae484828501611c53565b60008301525092915050565b600060208284031215612b0657612b05611361565b5b600082015167ffffffffffffffff811115612b2457612b23611366565b5b612b3084828501612a98565b91505092915050565b60006020830160008301518482036000860152612b568282611ff7565b9150508091505092915050565b60006020820190508181036000830152612b7d8184612b39565b905092915050565b612b8e816115af565b8114612b9957600080fd5b50565b600081519050612bab81612b85565b92915050565b600060208284031215612bc757612bc6611361565b5b6000612bd584828501612b9c565b91505092915050565b7f7472616e73666572416c6c6f77616e6365546f00000000000000000000000000600082015250565b6000612c14601383612281565b9150612c1f82612bde565b602082019050919050565b60006020820190508181036000830152612c4381612c07565b9050919050565b612c538161245f565b82525050565b60006020830160008301518482036000860152612c768282612521565b9150508091505092915050565b6000608082019050612c986000830187612c4a565b612ca56020830186612c4a565b8181036040830152612cb78185612c59565b90508181036060830152612ccb81846121fa565b905095945050505050565b600067ffffffffffffffff821115612cf157612cf0611381565b5b602082029050602081019050919050565b600060408284031215612d1857612d1761136b565b5b612d2260406113e1565b9050600082015167ffffffffffffffff811115612d4257612d416113fc565b5b612d4e84828501611c53565b600083015250602082015167ffffffffffffffff811115612d7257612d716113fc565b5b612d7e84828501611c53565b60208301525092915050565b6000612d9d612d9884612cd6565b6113e1565b90508083825260208201905060208402830185811115612dc057612dbf611701565b5b835b81811015612e0757805167ffffffffffffffff811115612de557612de4611401565b5b808601612df28982612d02565b85526020850194505050602081019050612dc2565b5050509392505050565b600082601f830112612e2657612e25611401565b5b8151612e36848260208601612d8a565b91505092915050565b600060208284031215612e5557612e5461136b565b5b612e5f60206113e1565b9050600082015167ffffffffffffffff811115612e7f57612e7e6113fc565b5b612e8b84828501612e11565b60008301525092915050565b600060208284031215612ead57612eac611361565b5b600082015167ffffffffffffffff811115612ecb57612eca611366565b5b612ed784828501612e3f565b91505092915050565b600081519050919050565b6000612ef682612ee0565b612f008185612281565b9350612f10818560208601611be7565b612f1981611370565b840191505092915050565b60006020820190508181036000830152612f3e8184612eeb565b905092915050565b7f696e63636f756e74657200000000000000000000000000000000000000000000600082015250565b6000612f7c600a83612281565b9150612f8782612f46565b602082019050919050565b60006020820190508181036000830152612fab81612f6f565b9050919050565b7f696e63436f756e74657200000000000000000000000000000000000000000000600082015250565b6000612fe8600a83612281565b9150612ff382612fb2565b602082019050919050565b6000602082019050818103600083015261301781612fdb565b9050919050565b7f676f7665726e616e636500000000000000000000000000000000000000000000600082015250565b6000613054600a83612281565b915061305f8261301e565b602082019050919050565b6000602082019050818103600083015261308381613047565b9050919050565b7f636c61696d436861696e4f776e65727368690000000000000000000000000000600082015250565b60006130c0601283612281565b91506130cb8261308a565b602082019050919050565b600060208201905081810360008301526130ef816130b3565b905091905056fea26469706673582212206c779ecaabfcaf5402930e97f08e61fb3d13e69bcb23acfa927afc0614fa472364736f6c63430008100033 \ No newline at end of file diff --git a/packages/vm/core/evm/evmimpl/impl.go b/packages/vm/core/evm/evmimpl/impl.go index 1a91b3abe3..c8c3fd8753 100644 --- a/packages/vm/core/evm/evmimpl/impl.go +++ b/packages/vm/core/evm/evmimpl/impl.go @@ -18,6 +18,7 @@ import ( "github.com/iotaledger/wasp/packages/util/panicutil" "github.com/iotaledger/wasp/packages/vm/core/evm" "github.com/iotaledger/wasp/packages/vm/core/evm/emulator" + "github.com/iotaledger/wasp/packages/vm/core/evm/iscmagic" "github.com/iotaledger/wasp/packages/vm/gas" ) @@ -63,6 +64,14 @@ func initialize(ctx isc.Sandbox) dict.Dict { // add the standard ISC contract at arbitrary address 0x1074 deployMagicContractOnGenesis(genesisAlloc) + // add the standard ERC20 provider at address 0x1075 + genesisAlloc[iscmagic.ERC20BaseTokensAddress] = core.GenesisAccount{ + Code: iscmagic.ERC20BaseTokensRuntimeBytecode, + Storage: map[common.Hash]common.Hash{}, + Balance: &big.Int{}, + } + addToPrivileged(ctx, iscmagic.ERC20BaseTokensAddress) + chainID := evmtypes.MustDecodeChainID(ctx.Params().MustGet(evm.FieldChainID), evm.DefaultChainID) emulator.Init( evmStateSubrealm(ctx.State()), @@ -76,6 +85,7 @@ func initialize(ctx isc.Sandbox) dict.Dict { gasRatio := codec.MustDecodeRatio32(ctx.Params().MustGet(evm.FieldGasRatio), evmtypes.DefaultGasRatio) ctx.State().Set(keyGasRatio, gasRatio.Bytes()) + // storing hname as a terminal value of the contract's state nil key. // This way we will be able to retrieve commitment to the contract's state ctx.State().Set("", ctx.Contract().Bytes()) @@ -225,6 +235,7 @@ func callContract(ctx isc.SandboxView) dict.Dict { emu := createEmulatorR(ctx) res, err := emu.CallContract(callMsg, nil) ctx.RequireNoError(err) + ctx.RequireNoError(res.Err) return result(res.Return()) } @@ -243,6 +254,7 @@ func estimateGas(ctx isc.Sandbox) dict.Dict { emu := createEmulator(ctx) res, err := emu.CallContract(callMsg, ctx.Privileged().GasBurnEnable) ctx.RequireNoError(err) + ctx.RequireNoError(res.Err) // TODO: this assumes that the initial budget was gas.MaxGasPerCall // see evmOffLedgerEstimateGasRequest::GasBudget() diff --git a/packages/vm/core/evm/evmimpl/iscmagic.go b/packages/vm/core/evm/evmimpl/iscmagic.go index c692e22fa1..d4822f422f 100644 --- a/packages/vm/core/evm/evmimpl/iscmagic.go +++ b/packages/vm/core/evm/evmimpl/iscmagic.go @@ -18,13 +18,69 @@ import ( "github.com/iotaledger/wasp/packages/isc" "github.com/iotaledger/wasp/packages/kv" "github.com/iotaledger/wasp/packages/kv/codec" + "github.com/iotaledger/wasp/packages/parameters" "github.com/iotaledger/wasp/packages/util/panicutil" "github.com/iotaledger/wasp/packages/vm/core/evm/iscmagic" "github.com/iotaledger/wasp/packages/vm/vmcontext/vmexceptions" ) +const ( + prefixPrivileged = "p" + prefixAllowance = "a" +) + +// directory of EVM contracts that have access to the privileged methods of ISC magic +func keyPrivileged(addr common.Address) kv.Key { + return kv.Key(prefixPrivileged) + kv.Key(addr.Bytes()) +} + +func isPrivileged(ctx isc.SandboxBase, addr common.Address) bool { + state := iscMagicSubrealmR(ctx.StateR()) + return state.MustHas(keyPrivileged(addr)) +} + +func addToPrivileged(ctx isc.Sandbox, addr common.Address) { + state := iscMagicSubrealm(ctx.State()) + state.Set(keyPrivileged(addr), []byte{1}) +} + +// allowance between two EVM accounts func keyAllowance(from, to common.Address) kv.Key { - return kv.Key("a") + kv.Key(from.Bytes()) + kv.Key(to.Bytes()) + return kv.Key(prefixAllowance) + kv.Key(from.Bytes()) + kv.Key(to.Bytes()) +} + +func getAllowance(ctx isc.SandboxBase, from, to common.Address) *isc.Allowance { + state := iscMagicSubrealmR(ctx.StateR()) + key := keyAllowance(from, to) + return codec.MustDecodeAllowance(state.MustGet(key), isc.NewEmptyAllowance()) +} + +func addToAllowance(ctx isc.Sandbox, from, to common.Address, add *isc.Allowance) { + state := iscMagicSubrealm(ctx.State()) + key := keyAllowance(from, to) + allowance := codec.MustDecodeAllowance(state.MustGet(key), isc.NewEmptyAllowance()) + allowance.Add(add) + state.Set(key, allowance.Bytes()) +} + +func subtractFromAllowance(ctx isc.Sandbox, from, to common.Address, taken *isc.Allowance) *isc.Allowance { + state := iscMagicSubrealm(ctx.State()) + key := keyAllowance(from, to) + + remaining := codec.MustDecodeAllowance(state.MustGet(key), isc.NewEmptyAllowance()) + if taken.IsEmpty() { + taken = remaining.Clone() + } + + ok := remaining.SpendFromBudget(taken) + ctx.Requiref(ok, "takeAllowedFunds: not previously allowed") + if remaining.IsEmpty() { + state.Del(key) + } else { + state.Set(key, remaining.Bytes()) + } + + return taken } // deployMagicContractOnGenesis sets up the initial state of the ISC EVM contract @@ -39,7 +95,10 @@ func deployMagicContractOnGenesis(genesisAlloc core.GenesisAlloc) { } } -var iscABI abi.ABI +var ( + iscABI abi.ABI + iscPrivilegedABI abi.ABI +) func init() { var err error @@ -47,15 +106,23 @@ func init() { if err != nil { panic(err) } -} - -func parseCall(input []byte) (*abi.Method, []interface{}) { - method, err := iscABI.MethodById(input[:4]) + iscPrivilegedABI, err = abi.JSON(strings.NewReader(iscmagic.PrivilegedABI)) if err != nil { panic(err) } +} + +func parseCall(input []byte, privileged bool) (*abi.Method, []interface{}) { + var method *abi.Method + if privileged { + method, _ = iscPrivilegedABI.MethodById(input[:4]) + } if method == nil { - panic(fmt.Sprintf("iscmagic: method not found: %x", input[:4])) + var err error + method, err = iscABI.MethodById(input[:4]) + if err != nil { + panic(err) + } } args, err := method.Inputs.Unpack(input[4:]) if err != nil { @@ -97,57 +164,79 @@ func moveAssetsToCommonAccount(ctx isc.Sandbox, caller vm.ContractRef, fungibleT ) } -type RunFunc func(evm *vm.EVM, caller vm.ContractRef, input []byte, gas uint64, readOnly bool) (ret []byte, remainingGas uint64) +type RunFunc func(evm *vm.EVM, caller vm.ContractRef, input []byte, gas uint64, readOnly bool) []byte // catchISCPanics executes a `Run` function (either from a call or view), and catches ISC exceptions, if any ISC exception happens, ErrExecutionReverted is issued func catchISCPanics(run RunFunc, evm *vm.EVM, caller vm.ContractRef, input []byte, gas uint64, readOnly bool, log isc.LogInterface) (ret []byte, remainingGas uint64, err error) { err = panicutil.CatchAllExcept( func() { - ret, remainingGas = run(evm, caller, input, gas, readOnly) + ret = run(evm, caller, input, gas, readOnly) }, vmexceptions.AllProtocolLimits..., ) if err != nil { - remainingGas = gas log.Infof("EVM request failed with ISC panic, caller: %s, input: %s,err: %v", caller.Address(), hex.EncodeToString(input), err) // the ISC error is lost inside the EVM, a possible solution would be to wrap the ErrExecutionReverted error, but the ISC information still gets deleted at some point // err = errors.Wrap(vm.ErrExecutionReverted, err.Error()) err = vm.ErrExecutionReverted } - return ret, remainingGas, err + return ret, gas, err } func (c *magicContract) Run(evm *vm.EVM, caller vm.ContractRef, input []byte, gas uint64, readOnly bool) (ret []byte, remainingGas uint64, err error) { return catchISCPanics(c.doRun, evm, caller, input, gas, readOnly, c.ctx.Log()) } -//nolint:funlen -func (c *magicContract) doRun(evm *vm.EVM, caller vm.ContractRef, input []byte, gas uint64, readOnly bool) (ret []byte, remainingGas uint64) { - ret, remainingGas, _, ok := tryViewCall(c.ctx, caller, input, gas) - if ok { - return ret, remainingGas - } +func (c *magicContract) doRun(evm *vm.EVM, caller vm.ContractRef, input []byte, gas uint64, readOnly bool) []byte { + privileged := isPrivileged(c.ctx, caller.Address()) + method, args := parseCall(input, privileged) - remainingGas = gas - method, args := parseCall(input) var outs []interface{} + var ok bool + if privileged { + outs, ok = tryPrivilegedCall(c.ctx, caller, method, args) + } + if !ok { + outs, ok = tryUnprivilegedCall(c.ctx, caller, method, args) + } + if !ok { + panic(fmt.Sprintf("no handler for method %s", method.Name)) + } + ret, err := method.Outputs.Pack(outs...) + c.ctx.RequireNoError(err) + return ret +} + +func tryUnprivilegedCall(ctx isc.Sandbox, caller vm.ContractRef, method *abi.Method, args []interface{}) ([]interface{}, bool) { + if outs, ok := tryViewCall(ctx, caller, method, args); ok { + return outs, ok + } + if outs, ok := tryCall(ctx, caller, method, args); ok { + return outs, ok + } + return nil, false +} + +//nolint:funlen +func tryCall(ctx isc.Sandbox, caller vm.ContractRef, method *abi.Method, args []interface{}) ([]interface{}, bool) { switch method.Name { case "getEntropy": - outs = []interface{}{c.ctx.GetEntropy()} + return []interface{}{ctx.GetEntropy()}, true case "triggerEvent": - c.ctx.Event(args[0].(string)) + ctx.Event(args[0].(string)) + return nil, true case "getRequestID": - outs = []interface{}{c.ctx.Request().ID()} + return []interface{}{ctx.Request().ID()}, true case "getSenderAccount": - outs = []interface{}{iscmagic.WrapISCAgentID(c.ctx.Request().SenderAccount())} + return []interface{}{iscmagic.WrapISCAgentID(ctx.Request().SenderAccount())}, true case "registerError": errorMessage := args[0].(string) - outs = []interface{}{c.ctx.RegisterError(errorMessage).Create().Code().ID} + return []interface{}{ctx.RegisterError(errorMessage).Create().Code().ID}, true case "allow": params := struct { @@ -155,13 +244,9 @@ func (c *magicContract) doRun(evm *vm.EVM, caller vm.ContractRef, input []byte, Allowance iscmagic.ISCAllowance }{} err := method.Inputs.Copy(¶ms, args) - c.ctx.RequireNoError(err) - - state := iscMagicSubrealm(c.ctx.State()) - key := keyAllowance(caller.Address(), params.Target) - allowance := codec.MustDecodeAllowance(state.MustGet(key), isc.NewEmptyAllowance()) - allowance.Add(params.Allowance.Unwrap()) - state.Set(key, allowance.Bytes()) + ctx.RequireNoError(err) + addToAllowance(ctx, caller.Address(), params.Target, params.Allowance.Unwrap()) + return nil, true case "takeAllowedFunds": params := struct { @@ -169,31 +254,16 @@ func (c *magicContract) doRun(evm *vm.EVM, caller vm.ContractRef, input []byte, Allowance iscmagic.ISCAllowance }{} err := method.Inputs.Copy(¶ms, args) - c.ctx.RequireNoError(err) - - state := iscMagicSubrealm(c.ctx.State()) - key := keyAllowance(params.Addr, caller.Address()) - allowance := codec.MustDecodeAllowance(state.MustGet(key), isc.NewEmptyAllowance()) - - taken := params.Allowance.Unwrap() - if taken.IsEmpty() { - taken = allowance.Clone() - } - - ok := allowance.SpendFromBudget(taken) - c.ctx.Requiref(ok, "takeAllowedFunds: not previously allowed") - if allowance.IsEmpty() { - state.Del(key) - } else { - state.Set(key, allowance.Bytes()) - } + ctx.RequireNoError(err) - c.ctx.Privileged().MustMoveBetweenAccounts( + taken := subtractFromAllowance(ctx, params.Addr, caller.Address(), params.Allowance.Unwrap()) + ctx.Privileged().MustMoveBetweenAccounts( isc.NewEthereumAddressAgentID(params.Addr), isc.NewEthereumAddressAgentID(caller.Address()), taken.Assets, taken.NFTs, ) + return nil, true case "send": params := struct { @@ -204,7 +274,7 @@ func (c *magicContract) doRun(evm *vm.EVM, caller vm.ContractRef, input []byte, SendOptions iscmagic.ISCSendOptions }{} err := method.Inputs.Copy(¶ms, args) - c.ctx.RequireNoError(err) + ctx.RequireNoError(err) req := isc.RequestParameters{ TargetAddress: params.TargetAddress.MustUnwrap(), FungibleTokens: params.FungibleTokens.Unwrap(), @@ -212,17 +282,18 @@ func (c *magicContract) doRun(evm *vm.EVM, caller vm.ContractRef, input []byte, Metadata: params.Metadata.Unwrap(), Options: params.SendOptions.Unwrap(), } - adjustStorageDeposit(c.ctx, req) + adjustStorageDeposit(ctx, req) // make sure that allowance <= sent tokens, so that the target contract does not // spend from the common account - c.ctx.Requiref( + ctx.Requiref( isc.NewAllowanceFungibleTokens(req.FungibleTokens).SpendFromBudget(req.Metadata.Allowance), "allowance must not be greater than sent tokens", ) - moveAssetsToCommonAccount(c.ctx, caller, req.FungibleTokens, nil) - c.ctx.Send(req) + moveAssetsToCommonAccount(ctx, caller, req.FungibleTokens, nil) + ctx.Send(req) + return nil, true case "sendAsNFT": params := struct { @@ -234,7 +305,7 @@ func (c *magicContract) doRun(evm *vm.EVM, caller vm.ContractRef, input []byte, SendOptions iscmagic.ISCSendOptions }{} err := method.Inputs.Copy(¶ms, args) - c.ctx.RequireNoError(err) + ctx.RequireNoError(err) req := isc.RequestParameters{ TargetAddress: params.TargetAddress.MustUnwrap(), FungibleTokens: params.FungibleTokens.Unwrap(), @@ -243,17 +314,18 @@ func (c *magicContract) doRun(evm *vm.EVM, caller vm.ContractRef, input []byte, Options: params.SendOptions.Unwrap(), } nftID := params.NFTID.Unwrap() - adjustStorageDeposit(c.ctx, req) + adjustStorageDeposit(ctx, req) // make sure that allowance <= sent tokens, so that the target contract does not // spend from the common account - c.ctx.Requiref( + ctx.Requiref( isc.NewAllowanceFungibleTokens(req.FungibleTokens).AddNFTs(nftID).SpendFromBudget(req.Metadata.Allowance), "allowance must not be greater than sent tokens", ) - moveAssetsToCommonAccount(c.ctx, caller, req.FungibleTokens, []iotago.NFTID{nftID}) - c.ctx.SendAsNFT(req, nftID) + moveAssetsToCommonAccount(ctx, caller, req.FungibleTokens, []iotago.NFTID{nftID}) + ctx.SendAsNFT(req, nftID) + return nil, true case "call": var callArgs struct { @@ -263,24 +335,72 @@ func (c *magicContract) doRun(evm *vm.EVM, caller vm.ContractRef, input []byte, Allowance iscmagic.ISCAllowance } err := method.Inputs.Copy(&callArgs, args) - c.ctx.RequireNoError(err) + ctx.RequireNoError(err) allowance := callArgs.Allowance.Unwrap() - moveAssetsToCommonAccount(c.ctx, caller, allowance.Assets, allowance.NFTs) - callRet := c.ctx.Call( + moveAssetsToCommonAccount(ctx, caller, allowance.Assets, allowance.NFTs) + callRet := ctx.Call( isc.Hname(callArgs.ContractHname), isc.Hname(callArgs.EntryPoint), callArgs.Params.Unwrap(), allowance, ) - outs = []interface{}{iscmagic.WrapISCDict(callRet)} + return []interface{}{iscmagic.WrapISCDict(callRet)}, true + } + return nil, false +} - default: - panic(fmt.Sprintf("no handler for method %s", method.Name)) +//nolint:unparam +func tryPrivilegedCall(ctx isc.Sandbox, caller vm.ContractRef, method *abi.Method, args []interface{}) ([]interface{}, bool) { + if !isPrivileged(ctx, caller.Address()) { + return nil, false } + switch method.Name { + case "moveBetweenAccounts": + var params struct { + Sender common.Address + Receiver common.Address + Allowance iscmagic.ISCAllowance + } + err := method.Inputs.Copy(¶ms, args) + ctx.RequireNoError(err) + allowance := params.Allowance.Unwrap() + ctx.Privileged().MustMoveBetweenAccounts( + isc.NewEthereumAddressAgentID(params.Sender), + isc.NewEthereumAddressAgentID(params.Receiver), + allowance.Assets, + allowance.NFTs, + ) + return nil, true - ret, err := method.Outputs.Pack(outs...) - c.ctx.RequireNoError(err) - return ret, remainingGas + case "addToAllowance": + var params struct { + From common.Address + To common.Address + Allowance iscmagic.ISCAllowance + } + err := method.Inputs.Copy(¶ms, args) + ctx.RequireNoError(err) + addToAllowance(ctx, params.From, params.To, params.Allowance.Unwrap()) + return nil, true + + case "moveAllowedFunds": + var params struct { + From common.Address + To common.Address + Allowance iscmagic.ISCAllowance + } + err := method.Inputs.Copy(¶ms, args) + ctx.RequireNoError(err) + taken := subtractFromAllowance(ctx, params.From, params.To, params.Allowance.Unwrap()) + ctx.Privileged().MustMoveBetweenAccounts( + isc.NewEthereumAddressAgentID(params.From), + isc.NewEthereumAddressAgentID(params.To), + taken.Assets, + taken.NFTs, + ) + return nil, true + } + return nil, false } type magicContractView struct { @@ -295,38 +415,39 @@ func (c *magicContractView) Run(evm *vm.EVM, caller vm.ContractRef, input []byte return catchISCPanics(c.doRun, evm, caller, input, gas, readOnly, c.ctx.Log()) } -func (c *magicContractView) doRun(evm *vm.EVM, caller vm.ContractRef, input []byte, gas uint64, readOnly bool) (ret []byte, remainingGas uint64) { - ret, remainingGas, method, ok := tryViewCall(c.ctx, caller, input, gas) +func (c *magicContractView) doRun(evm *vm.EVM, caller vm.ContractRef, input []byte, gas uint64, readOnly bool) []byte { + method, args := parseCall(input, isPrivileged(c.ctx, caller.Address())) + + outs, ok := tryViewCall(c.ctx, caller, method, args) if !ok { panic(fmt.Sprintf("no handler for method %s", method.Name)) } - return ret, remainingGas -} -func tryViewCall(ctx isc.SandboxBase, caller vm.ContractRef, input []byte, gas uint64) (ret []byte, remainingGas uint64, method *abi.Method, ok bool) { - remainingGas = gas - method, args := parseCall(input) - var outs []interface{} + ret, err := method.Outputs.Pack(outs...) + c.ctx.RequireNoError(err) + return ret +} +func tryViewCall(ctx isc.SandboxBase, caller vm.ContractRef, method *abi.Method, args []interface{}) (outs []interface{}, ok bool) { switch method.Name { case "hn": - outs = []interface{}{isc.Hn(args[0].(string))} + return []interface{}{isc.Hn(args[0].(string))}, true case "getChainID": - outs = []interface{}{iscmagic.WrapISCChainID(ctx.ChainID())} + return []interface{}{iscmagic.WrapISCChainID(ctx.ChainID())}, true case "getChainOwnerID": - outs = []interface{}{iscmagic.WrapISCAgentID(ctx.ChainOwnerID())} + return []interface{}{iscmagic.WrapISCAgentID(ctx.ChainOwnerID())}, true case "getNFTData": var nftID iscmagic.NFTID err := method.Inputs.Copy(&nftID, args) ctx.RequireNoError(err) nft := ctx.GetNFTData(nftID.Unwrap()) - outs = []interface{}{iscmagic.WrapISCNFT(&nft)} + return []interface{}{iscmagic.WrapISCNFT(&nft)}, true case "getTimestampUnixSeconds": - outs = []interface{}{ctx.Timestamp().Unix()} + return []interface{}{ctx.Timestamp().Unix()}, true case "callView": var callViewArgs struct { @@ -341,34 +462,44 @@ func tryViewCall(ctx isc.SandboxBase, caller vm.ContractRef, input []byte, gas u isc.Hname(callViewArgs.EntryPoint), callViewArgs.Params.Unwrap(), ) - outs = []interface{}{iscmagic.WrapISCDict(callRet)} + return []interface{}{iscmagic.WrapISCDict(callRet)}, true case "getAllowanceFrom": var addr common.Address err := method.Inputs.Copy(&addr, args) ctx.RequireNoError(err) - - state := iscMagicSubrealmR(ctx.StateR()) - key := keyAllowance(addr, caller.Address()) - allowance := codec.MustDecodeAllowance(state.MustGet(key), isc.NewEmptyAllowance()) - outs = []interface{}{iscmagic.WrapISCAllowance(allowance)} + return []interface{}{iscmagic.WrapISCAllowance(getAllowance(ctx, addr, caller.Address()))}, true case "getAllowanceTo": var target common.Address err := method.Inputs.Copy(&target, args) ctx.RequireNoError(err) + return []interface{}{iscmagic.WrapISCAllowance(getAllowance(ctx, caller.Address(), target))}, true - state := iscMagicSubrealmR(ctx.StateR()) - key := keyAllowance(caller.Address(), target) - allowance := codec.MustDecodeAllowance(state.MustGet(key), isc.NewEmptyAllowance()) - outs = []interface{}{iscmagic.WrapISCAllowance(allowance)} - - default: - return + case "getAllowance": + var params struct { + From common.Address + To common.Address + } + err := method.Inputs.Copy(¶ms, args) + ctx.RequireNoError(err) + return []interface{}{iscmagic.WrapISCAllowance(getAllowance(ctx, params.From, params.To))}, true + + case "getBaseTokenProperties": + l1 := parameters.L1() + return []interface{}{iscmagic.ISCTokenProperties{ + Name: l1.BaseToken.Name, + TickerSymbol: l1.BaseToken.TickerSymbol, + Decimals: uint8(l1.BaseToken.Decimals), + TotalSupply: big.NewInt(int64(l1.Protocol.TokenSupply)), + }}, true + + case "print": + var s string + err := method.Inputs.Copy(&s, args) + ctx.RequireNoError(err) + ctx.Log().Debugf("isc.print() -> %q", s) + return nil, true } - - ok = true - ret, err := method.Outputs.Pack(outs...) - ctx.RequireNoError(err) - return ret, remainingGas, method, ok + return nil, false } diff --git a/packages/vm/core/evm/evmtest/evm_test.go b/packages/vm/core/evm/evmtest/evm_test.go index 9b0ef8f889..0886fe701e 100644 --- a/packages/vm/core/evm/evmtest/evm_test.go +++ b/packages/vm/core/evm/evmtest/evm_test.go @@ -12,6 +12,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" "github.com/stretchr/testify/require" "github.com/iotaledger/iota.go/v3/tpkg" @@ -22,6 +23,7 @@ import ( "github.com/iotaledger/wasp/packages/isc" "github.com/iotaledger/wasp/packages/kv/codec" "github.com/iotaledger/wasp/packages/kv/dict" + "github.com/iotaledger/wasp/packages/parameters" "github.com/iotaledger/wasp/packages/solo" "github.com/iotaledger/wasp/packages/util" "github.com/iotaledger/wasp/packages/vm" @@ -177,12 +179,16 @@ func TestNotEnoughISCGas(t *testing.T) { require.NoError(t, err) require.Equal(t, newGasRatio, env.getGasRatio()) + senderAddress := crypto.PubkeyToAddress(storage.defaultSender.PublicKey) + nonce := env.getNonce(senderAddress) + // try to issue a call to store(something) in EVM res, err := storage.store(44) // the call must fail with "not enough gas" require.Error(t, err) require.Regexp(t, "gas budget exceeded", err) + require.Equal(t, nonce+1, env.getNonce(senderAddress)) // there must be an EVM receipt require.NotNil(t, res.evmReceipt) @@ -609,3 +615,101 @@ func TestSendWithArgs(t *testing.T) { // assert inc counter was incremented checkCounter(1) } + +func TestERC20BaseTokens(t *testing.T) { + env := initEVM(t) + ethKey, ethAddr := env.soloChain.NewEthereumAccountWithL2Funds() + + erc20 := env.ERC20BaseTokens(ethKey) + + { + var name string + erc20.callView("name", nil, &name) + require.Equal(t, parameters.L1().BaseToken.Name, name) + } + { + var sym string + erc20.callView("symbol", nil, &sym) + require.Equal(t, parameters.L1().BaseToken.TickerSymbol, sym) + } + { + var dec uint8 + erc20.callView("decimals", nil, &dec) + require.EqualValues(t, parameters.L1().BaseToken.Decimals, dec) + } + { + var supply *big.Int + erc20.callView("totalSupply", nil, &supply) + require.Equal(t, parameters.L1().Protocol.TokenSupply, supply.Uint64()) + } + { + var balance *big.Int + erc20.callView("balanceOf", []interface{}{ethAddr}, &balance) + require.EqualValues(t, + env.soloChain.L2BaseTokens(isc.NewEthereumAddressAgentID(ethAddr)), + balance.Uint64(), + ) + } + { + initialBalance := env.soloChain.L2BaseTokens(isc.NewEthereumAddressAgentID(ethAddr)) + _, ethAddr2 := solo.NewEthereumAccount() + _, err := erc20.callFn(nil, "transfer", ethAddr2, big.NewInt(int64(1*isc.Million))) + require.NoError(t, err) + require.LessOrEqual(t, + env.soloChain.L2BaseTokens(isc.NewEthereumAddressAgentID(ethAddr)), + initialBalance-1*isc.Million, + ) + require.EqualValues(t, + 1*isc.Million, + env.soloChain.L2BaseTokens(isc.NewEthereumAddressAgentID(ethAddr2)), + ) + } + { + initialBalance := env.soloChain.L2BaseTokens(isc.NewEthereumAddressAgentID(ethAddr)) + ethKey2, ethAddr2 := env.soloChain.NewEthereumAccountWithL2Funds() + initialBalance2 := env.soloChain.L2BaseTokens(isc.NewEthereumAddressAgentID(ethAddr2)) + { + _, err := erc20.callFn(nil, "approve", ethAddr2, big.NewInt(int64(1*isc.Million))) + require.NoError(t, err) + require.Greater(t, + env.soloChain.L2BaseTokens(isc.NewEthereumAddressAgentID(ethAddr)), + initialBalance-1*isc.Million, + ) + require.EqualValues(t, + initialBalance2, + env.soloChain.L2BaseTokens(isc.NewEthereumAddressAgentID(ethAddr2)), + ) + } + + { + var allowance *big.Int + erc20.callView("allowance", []interface{}{ethAddr, ethAddr2}, &allowance) + require.EqualValues(t, + 1*isc.Million, + allowance.Uint64(), + ) + } + { + const amount = 100_000 + _, ethAddr3 := solo.NewEthereumAccount() + _, err := erc20.callFn([]ethCallOptions{{sender: ethKey2}}, "transferFrom", ethAddr, ethAddr3, big.NewInt(int64(amount))) + require.NoError(t, err) + require.Less(t, + initialBalance-1*isc.Million, + env.soloChain.L2BaseTokens(isc.NewEthereumAddressAgentID(ethAddr)), + ) + require.EqualValues(t, + amount, + env.soloChain.L2BaseTokens(isc.NewEthereumAddressAgentID(ethAddr3)), + ) + { + var allowance *big.Int + erc20.callView("allowance", []interface{}{ethAddr, ethAddr2}, &allowance) + require.EqualValues(t, + 1*isc.Million-amount, + allowance.Uint64(), + ) + } + } + } +} diff --git a/packages/vm/core/evm/evmtest/utils_test.go b/packages/vm/core/evm/evmtest/utils_test.go index f79dcc7692..647bcf3c2f 100644 --- a/packages/vm/core/evm/evmtest/utils_test.go +++ b/packages/vm/core/evm/evmtest/utils_test.go @@ -216,6 +216,19 @@ func (e *soloChainEnv) MagicContract(defaultSender *ecdsa.PrivateKey) *iscContra } } +func (e *soloChainEnv) ERC20BaseTokens(defaultSender *ecdsa.PrivateKey) *iscContractInstance { + erc20BaseABI, err := abi.JSON(strings.NewReader(iscmagic.ERC20BaseTokensABI)) + require.NoError(e.t, err) + return &iscContractInstance{ + evmContractInstance: &evmContractInstance{ + chain: e, + defaultSender: defaultSender, + address: iscmagic.ERC20BaseTokensAddress, + abi: erc20BaseABI, + }, + } +} + func (e *soloChainEnv) deployISCTestContract(creator *ecdsa.PrivateKey) *iscTestContractInstance { return &iscTestContractInstance{e.deployContract(creator, evmtest.ISCTestContractABI, evmtest.ISCTestContractBytecode)} } diff --git a/packages/vm/core/evm/iscmagic/.gitignore b/packages/vm/core/evm/iscmagic/.gitignore new file mode 100644 index 0000000000..42d1da4cd2 --- /dev/null +++ b/packages/vm/core/evm/iscmagic/.gitignore @@ -0,0 +1,4 @@ +ISC.bin-runtime +ISCLib.abi +ISCLib.bin-runtime +ISCPrivileged.bin-runtime diff --git a/packages/vm/core/evm/iscmagic/ERC20BaseTokens.abi b/packages/vm/core/evm/iscmagic/ERC20BaseTokens.abi new file mode 100644 index 0000000000..b6b01cdc22 --- /dev/null +++ b/packages/vm/core/evm/iscmagic/ERC20BaseTokens.abi @@ -0,0 +1 @@ +[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"tokenOwner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokens","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokens","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"delegate","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"delegate","type":"address"},{"internalType":"uint256","name":"numTokens","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenOwner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","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":"receiver","type":"address"},{"internalType":"uint256","name":"numTokens","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"buyer","type":"address"},{"internalType":"uint256","name":"numTokens","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"}] \ No newline at end of file diff --git a/packages/vm/core/evm/iscmagic/ERC20BaseTokens.bin-runtime b/packages/vm/core/evm/iscmagic/ERC20BaseTokens.bin-runtime new file mode 100644 index 0000000000..9829ee7641 --- /dev/null +++ b/packages/vm/core/evm/iscmagic/ERC20BaseTokens.bin-runtime @@ -0,0 +1 @@ +608060405234801561001057600080fd5b50600436106100935760003560e01c8063313ce56711610066578063313ce5671461013457806370a082311461015257806395d89b4114610182578063a9059cbb146101a0578063dd62ed3e146101d057610093565b806306fdde0314610098578063095ea7b3146100b657806318160ddd146100e657806323b872dd14610104575b600080fd5b6100a0610200565b6040516100ad919061107f565b60405180910390f35b6100d060048036038101906100cb9190611149565b610281565b6040516100dd91906111a4565b60405180910390f35b6100ee6103d7565b6040516100fb91906111ce565b60405180910390f35b61011e600480360381019061011991906111e9565b610458565b60405161012b91906111a4565b60405180910390f35b61013c610654565b6040516101499190611258565b60405180910390f35b61016c60048036038101906101679190611273565b6106d5565b60405161017991906111ce565b60405180910390f35b61018a6106fe565b604051610197919061107f565b60405180910390f35b6101ba60048036038101906101b59190611149565b61077f565b6040516101c791906111a4565b60405180910390f35b6101ea60048036038101906101e591906112a0565b6108d5565b6040516101f791906111ce565b60405180910390f35b606061107473ffffffffffffffffffffffffffffffffffffffff1663aaa89f256040518163ffffffff1660e01b8152600401600060405180830381865afa15801561024f573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906102789190611501565b60000151905090565b60006780000000000000008211156102ce576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102c590611596565b60405180910390fd5b6102d6610f84565b82816000019067ffffffffffffffff16908167ffffffffffffffff168152505061107473ffffffffffffffffffffffffffffffffffffffff1663072fad433386846040518463ffffffff1660e01b8152600401610335939291906118a6565b600060405180830381600087803b15801561034f57600080fd5b505af1158015610363573d6000803e3d6000fd5b505050508373ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925856040516103c491906111ce565b60405180910390a3600191505092915050565b600061107473ffffffffffffffffffffffffffffffffffffffff1663aaa89f256040518163ffffffff1660e01b8152600401600060405180830381865afa158015610426573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f8201168201806040525081019061044f9190611501565b60600151905090565b60006780000000000000008211156104a5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161049c90611596565b60405180910390fd5b6104ad610f84565b82816000019067ffffffffffffffff16908167ffffffffffffffff168152505061107473ffffffffffffffffffffffffffffffffffffffff16631e2d3c4e8633846040518463ffffffff1660e01b815260040161050c939291906118a6565b600060405180830381600087803b15801561052657600080fd5b505af115801561053a573d6000803e3d6000fd5b505050503373ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16146105e35761107473ffffffffffffffffffffffffffffffffffffffff1663a4b74d1b3386846040518463ffffffff1660e01b81526004016105b0939291906118a6565b600060405180830381600087803b1580156105ca57600080fd5b505af11580156105de573d6000803e3d6000fd5b505050505b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8560405161064091906111ce565b60405180910390a360019150509392505050565b600061107473ffffffffffffffffffffffffffffffffffffffff1663aaa89f256040518163ffffffff1660e01b8152600401600060405180830381865afa1580156106a3573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906106cc9190611501565b60400151905090565b6000806106e183610975565b90506106ec81610af1565b67ffffffffffffffff16915050919050565b606061107473ffffffffffffffffffffffffffffffffffffffff1663aaa89f256040518163ffffffff1660e01b8152600401600060405180830381865afa15801561074d573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906107769190611501565b60200151905090565b60006780000000000000008211156107cc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107c390611596565b60405180910390fd5b6107d4610f84565b82816000019067ffffffffffffffff16908167ffffffffffffffff168152505061107473ffffffffffffffffffffffffffffffffffffffff1663a4b74d1b3386846040518463ffffffff1660e01b8152600401610833939291906118a6565b600060405180830381600087803b15801561084d57600080fd5b505af1158015610861573d6000803e3d6000fd5b505050508373ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef856040516108c291906111ce565b60405180910390a3600191505092915050565b60008061107473ffffffffffffffffffffffffffffffffffffffff16630af4187d85856040518363ffffffff1660e01b81526004016109159291906118e4565b600060405180830381865afa158015610932573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f8201168201806040525081019061095b9190611d0f565b9050806000015167ffffffffffffffff1691505092915050565b61097d610faf565b6000826040516020016109909190611da0565b60405160208183030381529060405290506109a9610faf565b815160016109b79190611dea565b67ffffffffffffffff8111156109d0576109cf6112e5565b5b6040519080825280601f01601f191660200182016040528015610a025781602001600182028036833780820191505090505b508160000181905250600360f81b8160000151600081518110610a2857610a27611e1e565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060005b8251811015610ae657828181518110610a7657610a75611e1e565b5b602001015160f81c60f81b8260000151600183610a939190611dea565b81518110610aa457610aa3611e1e565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508080610ade90611e4d565b915050610a5a565b508092505050919050565b6000610afb610fc2565b600167ffffffffffffffff811115610b1657610b156112e5565b5b604051908082528060200260200182016040528015610b4f57816020015b610b3c610fd5565b815260200190600190039081610b345790505b5081600001819052506040518060400160405280600181526020017f61000000000000000000000000000000000000000000000000000000000000008152508160000151600081518110610ba657610ba5611e1e565b5b60200260200101516000018190525082600001518160000151600081518110610bd257610bd1611e1e565b5b602002602001015160200181905250600061107473ffffffffffffffffffffffffffffffffffffffff16630a26061761107473ffffffffffffffffffffffffffffffffffffffff1663dbfb12ef6040518163ffffffff1660e01b8152600401610c3a90611ee1565b602060405180830381865afa158015610c57573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c7b9190611f3d565b61107473ffffffffffffffffffffffffffffffffffffffff1663dbfb12ef6040518163ffffffff1660e01b8152600401610cb490611fb6565b602060405180830381865afa158015610cd1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cf59190611f3d565b856040518463ffffffff1660e01b8152600401610d1493929190612141565b600060405180830381865afa158015610d31573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190610d5a9190612340565b905060005b816000015151811015610e6d57600182600001518281518110610d8557610d84611e1e565b5b60200260200101516000015151148015610e2057507f420000000000000000000000000000000000000000000000000000000000000082600001518281518110610dd257610dd1611e1e565b5b602002602001015160000151600081518110610df157610df0611e1e565b5b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b15610e5a57610e5082600001518281518110610e3f57610e3e611e1e565b5b602002602001015160200151610eae565b9350505050610ea9565b8080610e6590611e4d565b915050610d5f565b506040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ea0906123d5565b60405180910390fd5b919050565b60006008825114610ef4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610eeb90612441565b60405180910390fd5b610efd82610f04565b9050919050565b60008060005b8351811015610f7a57806008610f209190612461565b6002610f2c91906125ee565b848281518110610f3f57610f3e611e1e565b5b602001015160f81c60f81b60f81c60ff16610f5a9190612461565b82610f659190611dea565b91508080610f7290611e4d565b915050610f0a565b5080915050919050565b6040518060600160405280600067ffffffffffffffff16815260200160608152602001606081525090565b6040518060200160405280606081525090565b6040518060200160405280606081525090565b604051806040016040528060608152602001606081525090565b600081519050919050565b600082825260208201905092915050565b60005b8381101561102957808201518184015260208101905061100e565b60008484015250505050565b6000601f19601f8301169050919050565b600061105182610fef565b61105b8185610ffa565b935061106b81856020860161100b565b61107481611035565b840191505092915050565b600060208201905081810360008301526110998184611046565b905092915050565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006110e0826110b5565b9050919050565b6110f0816110d5565b81146110fb57600080fd5b50565b60008135905061110d816110e7565b92915050565b6000819050919050565b61112681611113565b811461113157600080fd5b50565b6000813590506111438161111d565b92915050565b600080604083850312156111605761115f6110ab565b5b600061116e858286016110fe565b925050602061117f85828601611134565b9150509250929050565b60008115159050919050565b61119e81611189565b82525050565b60006020820190506111b96000830184611195565b92915050565b6111c881611113565b82525050565b60006020820190506111e360008301846111bf565b92915050565b600080600060608486031215611202576112016110ab565b5b6000611210868287016110fe565b9350506020611221868287016110fe565b925050604061123286828701611134565b9150509250925092565b600060ff82169050919050565b6112528161123c565b82525050565b600060208201905061126d6000830184611249565b92915050565b600060208284031215611289576112886110ab565b5b6000611297848285016110fe565b91505092915050565b600080604083850312156112b7576112b66110ab565b5b60006112c5858286016110fe565b92505060206112d6858286016110fe565b9150509250929050565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61131d82611035565b810181811067ffffffffffffffff8211171561133c5761133b6112e5565b5b80604052505050565b600061134f6110a1565b905061135b8282611314565b919050565b600080fd5b600080fd5b600080fd5b600067ffffffffffffffff82111561138a576113896112e5565b5b61139382611035565b9050602081019050919050565b60006113b36113ae8461136f565b611345565b9050828152602081018484840111156113cf576113ce61136a565b5b6113da84828561100b565b509392505050565b600082601f8301126113f7576113f6611365565b5b81516114078482602086016113a0565b91505092915050565b6114198161123c565b811461142457600080fd5b50565b60008151905061143681611410565b92915050565b60008151905061144b8161111d565b92915050565b600060808284031215611467576114666112e0565b5b6114716080611345565b9050600082015167ffffffffffffffff81111561149157611490611360565b5b61149d848285016113e2565b600083015250602082015167ffffffffffffffff8111156114c1576114c0611360565b5b6114cd848285016113e2565b60208301525060406114e184828501611427565b60408301525060606114f58482850161143c565b60608301525092915050565b600060208284031215611517576115166110ab565b5b600082015167ffffffffffffffff811115611535576115346110b0565b5b61154184828501611451565b91505092915050565b7f616d6f756e7420697320746f6f206c6172676500000000000000000000000000600082015250565b6000611580601383610ffa565b915061158b8261154a565b602082019050919050565b600060208201905081810360008301526115af81611573565b9050919050565b6115bf816110d5565b82525050565b600067ffffffffffffffff82169050919050565b6115e2816115c5565b82525050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b600081519050919050565b600082825260208201905092915050565b600061163b82611614565b611645818561161f565b935061165581856020860161100b565b61165e81611035565b840191505092915050565b600060208301600083015184820360008601526116868282611630565b9150508091505092915050565b61169c81611113565b82525050565b600060408301600083015184820360008601526116bf8282611669565b91505060208301516116d46020860182611693565b508091505092915050565b60006116eb83836116a2565b905092915050565b6000602082019050919050565b600061170b826115e8565b61171581856115f3565b93508360208202850161172785611604565b8060005b85811015611763578484038952815161174485826116df565b945061174f836116f3565b925060208a0199505060018101905061172b565b50829750879550505050505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6000819050919050565b60006117b6826117a1565b9050919050565b6117c6816117ab565b82525050565b60006117d883836117bd565b60208301905092915050565b6000602082019050919050565b60006117fc82611775565b6118068185611780565b935061181183611791565b8060005b8381101561184257815161182988826117cc565b9750611834836117e4565b925050600181019050611815565b5085935050505092915050565b600060608301600083015161186760008601826115d9565b506020830151848203602086015261187f8282611700565b9150506040830151848203604086015261189982826117f1565b9150508091505092915050565b60006060820190506118bb60008301866115b6565b6118c860208301856115b6565b81810360408301526118da818461184f565b9050949350505050565b60006040820190506118f960008301856115b6565b61190660208301846115b6565b9392505050565b611916816115c5565b811461192157600080fd5b50565b6000815190506119338161190d565b92915050565b600067ffffffffffffffff821115611954576119536112e5565b5b602082029050602081019050919050565b600080fd5b600067ffffffffffffffff821115611985576119846112e5565b5b61198e82611035565b9050602081019050919050565b60006119ae6119a98461196a565b611345565b9050828152602081018484840111156119ca576119c961136a565b5b6119d584828561100b565b509392505050565b600082601f8301126119f2576119f1611365565b5b8151611a0284826020860161199b565b91505092915050565b600060208284031215611a2157611a206112e0565b5b611a2b6020611345565b9050600082015167ffffffffffffffff811115611a4b57611a4a611360565b5b611a57848285016119dd565b60008301525092915050565b600060408284031215611a7957611a786112e0565b5b611a836040611345565b9050600082015167ffffffffffffffff811115611aa357611aa2611360565b5b611aaf84828501611a0b565b6000830152506020611ac38482850161143c565b60208301525092915050565b6000611ae2611add84611939565b611345565b90508083825260208201905060208402830185811115611b0557611b04611965565b5b835b81811015611b4c57805167ffffffffffffffff811115611b2a57611b29611365565b5b808601611b378982611a63565b85526020850194505050602081019050611b07565b5050509392505050565b600082601f830112611b6b57611b6a611365565b5b8151611b7b848260208601611acf565b91505092915050565b600067ffffffffffffffff821115611b9f57611b9e6112e5565b5b602082029050602081019050919050565b611bb9816117a1565b8114611bc457600080fd5b50565b600081519050611bd681611bb0565b92915050565b6000611bef611bea84611b84565b611345565b90508083825260208201905060208402830185811115611c1257611c11611965565b5b835b81811015611c3b5780611c278882611bc7565b845260208401935050602081019050611c14565b5050509392505050565b600082601f830112611c5a57611c59611365565b5b8151611c6a848260208601611bdc565b91505092915050565b600060608284031215611c8957611c886112e0565b5b611c936060611345565b90506000611ca384828501611924565b600083015250602082015167ffffffffffffffff811115611cc757611cc6611360565b5b611cd384828501611b56565b602083015250604082015167ffffffffffffffff811115611cf757611cf6611360565b5b611d0384828501611c45565b60408301525092915050565b600060208284031215611d2557611d246110ab565b5b600082015167ffffffffffffffff811115611d4357611d426110b0565b5b611d4f84828501611c73565b91505092915050565b60008160601b9050919050565b6000611d7082611d58565b9050919050565b6000611d8282611d65565b9050919050565b611d9a611d95826110d5565b611d77565b82525050565b6000611dac8284611d89565b60148201915081905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000611df582611113565b9150611e0083611113565b9250828201905080821115611e1857611e17611dbb565b5b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000611e5882611113565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611e8a57611e89611dbb565b5b600182019050919050565b7f6163636f756e7473000000000000000000000000000000000000000000000000600082015250565b6000611ecb600883610ffa565b9150611ed682611e95565b602082019050919050565b60006020820190508181036000830152611efa81611ebe565b9050919050565b600063ffffffff82169050919050565b611f1a81611f01565b8114611f2557600080fd5b50565b600081519050611f3781611f11565b92915050565b600060208284031215611f5357611f526110ab565b5b6000611f6184828501611f28565b91505092915050565b7f62616c616e636542617365546f6b656e00000000000000000000000000000000600082015250565b6000611fa0601083610ffa565b9150611fab82611f6a565b602082019050919050565b60006020820190508181036000830152611fcf81611f93565b9050919050565b6000819050919050565b6000611ffb611ff6611ff184611f01565b611fd6565b611f01565b9050919050565b61200b81611fe0565b82525050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6000604083016000830151848203600086015261205a8282611630565b915050602083015184820360208601526120748282611630565b9150508091505092915050565b600061208d838361203d565b905092915050565b6000602082019050919050565b60006120ad82612011565b6120b7818561201c565b9350836020820285016120c98561202d565b8060005b8581101561210557848403895281516120e68582612081565b94506120f183612095565b925060208a019950506001810190506120cd565b50829750879550505050505092915050565b6000602083016000830151848203600086015261213482826120a2565b9150508091505092915050565b60006060820190506121566000830186612002565b6121636020830185612002565b81810360408301526121758184612117565b9050949350505050565b600067ffffffffffffffff82111561219a576121996112e5565b5b602082029050602081019050919050565b6000604082840312156121c1576121c06112e0565b5b6121cb6040611345565b9050600082015167ffffffffffffffff8111156121eb576121ea611360565b5b6121f7848285016119dd565b600083015250602082015167ffffffffffffffff81111561221b5761221a611360565b5b612227848285016119dd565b60208301525092915050565b60006122466122418461217f565b611345565b9050808382526020820190506020840283018581111561226957612268611965565b5b835b818110156122b057805167ffffffffffffffff81111561228e5761228d611365565b5b80860161229b89826121ab565b8552602085019450505060208101905061226b565b5050509392505050565b600082601f8301126122cf576122ce611365565b5b81516122df848260208601612233565b91505092915050565b6000602082840312156122fe576122fd6112e0565b5b6123086020611345565b9050600082015167ffffffffffffffff81111561232857612327611360565b5b612334848285016122ba565b60008301525092915050565b600060208284031215612356576123556110ab565b5b600082015167ffffffffffffffff811115612374576123736110b0565b5b612380848285016122e8565b91505092915050565b7f736f6d657468696e672077656e742077726f6e67000000000000000000000000600082015250565b60006123bf601483610ffa565b91506123ca82612389565b602082019050919050565b600060208201905081810360008301526123ee816123b2565b9050919050565b7f6465636f646555696e7436343a20657870656374656420382062797465730000600082015250565b600061242b601e83610ffa565b9150612436826123f5565b602082019050919050565b6000602082019050818103600083015261245a8161241e565b9050919050565b600061246c82611113565b915061247783611113565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156124b0576124af611dbb565b5b828202905092915050565b60008160011c9050919050565b6000808291508390505b6001851115612512578086048111156124ee576124ed611dbb565b5b60018516156124fd5780820291505b808102905061250b856124bb565b94506124d2565b94509492505050565b60008261252b57600190506125e7565b8161253957600090506125e7565b816001811461254f576002811461255957612588565b60019150506125e7565b60ff84111561256b5761256a611dbb565b5b8360020a91508482111561258257612581611dbb565b5b506125e7565b5060208310610133831016604e8410600b84101617156125bd5782820a9050838111156125b8576125b7611dbb565b5b6125e7565b6125ca84848460016124c8565b925090508184048111156125e1576125e0611dbb565b5b81810290505b9392505050565b60006125f982611113565b915061260483611113565b92506126317fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff848461251b565b90509291505056fea264697066735822122074b08c865040c9762fc004605fae5499f18030fe50870962d365dcbc5705231064736f6c63430008100033 \ No newline at end of file diff --git a/packages/vm/core/evm/iscmagic/ERC20BaseTokens.sol b/packages/vm/core/evm/iscmagic/ERC20BaseTokens.sol new file mode 100644 index 0000000000..608cc4fd7d --- /dev/null +++ b/packages/vm/core/evm/iscmagic/ERC20BaseTokens.sol @@ -0,0 +1,75 @@ +// Copyright 2020 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +pragma solidity >=0.8.11; + +import "@iscmagic/ISC.sol"; +import "@iscmagic/ISCLib.sol"; +import "@iscmagic/ISCPrivileged.sol"; + +uint constant MAX_UINT64 = 1 << 64 - 1; + +// The ERC20 contract for ISC L2 base tokens. +contract ERC20BaseTokens { + event Approval(address indexed tokenOwner, address indexed spender, uint tokens); + event Transfer(address indexed from, address indexed to, uint tokens); + + function name() public view returns (string memory) { + return isc.getBaseTokenProperties().name; + } + + function symbol() public view returns (string memory) { + return isc.getBaseTokenProperties().tickerSymbol; + } + + function decimals() public view returns (uint8) { + return isc.getBaseTokenProperties().decimals; + } + + function totalSupply() public view returns (uint256) { + return isc.getBaseTokenProperties().totalSupply; + } + + function balanceOf(address tokenOwner) public view returns (uint256) { + ISCAgentID memory ownerAgentID = ISCLib.newEthereumAgentID(tokenOwner); + return ISCLib.getL2BalanceBaseTokens(ownerAgentID); + } + + function transfer(address receiver, uint256 numTokens) public returns (bool) { + require(numTokens <= MAX_UINT64, "amount is too large"); + ISCAllowance memory assets; + assets.baseTokens = uint64(numTokens); + ISCPrivileged(address(isc)).moveBetweenAccounts(msg.sender, receiver, assets); + emit Transfer(msg.sender, receiver, numTokens); + return true; + } + + function approve(address delegate, uint256 numTokens) public returns (bool) { + require(numTokens <= MAX_UINT64, "amount is too large"); + ISCAllowance memory assets; + assets.baseTokens = uint64(numTokens); + ISCPrivileged(address(isc)).addToAllowance(msg.sender, delegate, assets); + emit Approval(msg.sender, delegate, numTokens); + return true; + } + + function allowance(address owner, address delegate) public view returns (uint) { + ISCAllowance memory assets = isc.getAllowance(owner, delegate); + return assets.baseTokens; + } + + function transferFrom(address owner, address buyer, uint256 numTokens) public returns (bool) { + require(numTokens <= MAX_UINT64, "amount is too large"); + ISCAllowance memory assets; + assets.baseTokens = uint64(numTokens); + ISCPrivileged(address(isc)).moveAllowedFunds(owner, msg.sender, assets); + if (buyer != msg.sender) { + ISCPrivileged(address(isc)).moveBetweenAccounts(msg.sender, buyer, assets); + } + emit Transfer(owner, buyer, numTokens); + return true; + } +} + +// Every ISC chain is initialized with an instance of the ERC20BaseTokens contract at address 0x1075 +ERC20BaseTokens constant erc20BaseTokens = ERC20BaseTokens(address(uint160(ISC_ADDRESS + 1))); diff --git a/packages/vm/core/evm/iscmagic/ISC.abi b/packages/vm/core/evm/iscmagic/ISC.abi index 50ae9f3cfc..080c8ab702 100644 --- a/packages/vm/core/evm/iscmagic/ISC.abi +++ b/packages/vm/core/evm/iscmagic/ISC.abi @@ -1 +1 @@ -[{"inputs":[{"internalType":"address","name":"target","type":"address"},{"components":[{"internalType":"uint64","name":"baseTokens","type":"uint64"},{"components":[{"components":[{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct NativeTokenID","name":"ID","type":"tuple"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct NativeToken[]","name":"tokens","type":"tuple[]"},{"internalType":"NFTID[]","name":"nfts","type":"bytes32[]"}],"internalType":"struct ISCAllowance","name":"allowance","type":"tuple"}],"name":"allow","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"ISCHname","name":"contractHname","type":"uint32"},{"internalType":"ISCHname","name":"entryPoint","type":"uint32"},{"components":[{"components":[{"internalType":"bytes","name":"key","type":"bytes"},{"internalType":"bytes","name":"value","type":"bytes"}],"internalType":"struct ISCDictItem[]","name":"items","type":"tuple[]"}],"internalType":"struct ISCDict","name":"params","type":"tuple"},{"components":[{"internalType":"uint64","name":"baseTokens","type":"uint64"},{"components":[{"components":[{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct NativeTokenID","name":"ID","type":"tuple"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct NativeToken[]","name":"tokens","type":"tuple[]"},{"internalType":"NFTID[]","name":"nfts","type":"bytes32[]"}],"internalType":"struct ISCAllowance","name":"allowance","type":"tuple"}],"name":"call","outputs":[{"components":[{"components":[{"internalType":"bytes","name":"key","type":"bytes"},{"internalType":"bytes","name":"value","type":"bytes"}],"internalType":"struct ISCDictItem[]","name":"items","type":"tuple[]"}],"internalType":"struct ISCDict","name":"","type":"tuple"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"ISCHname","name":"contractHname","type":"uint32"},{"internalType":"ISCHname","name":"entryPoint","type":"uint32"},{"components":[{"components":[{"internalType":"bytes","name":"key","type":"bytes"},{"internalType":"bytes","name":"value","type":"bytes"}],"internalType":"struct ISCDictItem[]","name":"items","type":"tuple[]"}],"internalType":"struct ISCDict","name":"params","type":"tuple"}],"name":"callView","outputs":[{"components":[{"components":[{"internalType":"bytes","name":"key","type":"bytes"},{"internalType":"bytes","name":"value","type":"bytes"}],"internalType":"struct ISCDictItem[]","name":"items","type":"tuple[]"}],"internalType":"struct ISCDict","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"getAllowanceFrom","outputs":[{"components":[{"internalType":"uint64","name":"baseTokens","type":"uint64"},{"components":[{"components":[{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct NativeTokenID","name":"ID","type":"tuple"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct NativeToken[]","name":"tokens","type":"tuple[]"},{"internalType":"NFTID[]","name":"nfts","type":"bytes32[]"}],"internalType":"struct ISCAllowance","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"target","type":"address"}],"name":"getAllowanceTo","outputs":[{"components":[{"internalType":"uint64","name":"baseTokens","type":"uint64"},{"components":[{"components":[{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct NativeTokenID","name":"ID","type":"tuple"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct NativeToken[]","name":"tokens","type":"tuple[]"},{"internalType":"NFTID[]","name":"nfts","type":"bytes32[]"}],"internalType":"struct ISCAllowance","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getChainID","outputs":[{"internalType":"ISCChainID","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getChainOwnerID","outputs":[{"components":[{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct ISCAgentID","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getEntropy","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"NFTID","name":"id","type":"bytes32"}],"name":"getNFTData","outputs":[{"components":[{"internalType":"NFTID","name":"ID","type":"bytes32"},{"components":[{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct L1Address","name":"issuer","type":"tuple"},{"internalType":"bytes","name":"metadata","type":"bytes"}],"internalType":"struct ISCNFT","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getRequestID","outputs":[{"components":[{"internalType":"ISCTransactionID","name":"transactionID","type":"bytes32"},{"internalType":"uint16","name":"transactionOutputIndex","type":"uint16"}],"internalType":"struct ISCRequestID","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getSenderAccount","outputs":[{"components":[{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct ISCAgentID","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTimestampUnixSeconds","outputs":[{"internalType":"int64","name":"","type":"int64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"s","type":"string"}],"name":"hn","outputs":[{"internalType":"ISCHname","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"s","type":"string"}],"name":"registerError","outputs":[{"internalType":"ISCError","name":"","type":"uint16"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct L1Address","name":"targetAddress","type":"tuple"},{"components":[{"internalType":"uint64","name":"baseTokens","type":"uint64"},{"components":[{"components":[{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct NativeTokenID","name":"ID","type":"tuple"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct NativeToken[]","name":"tokens","type":"tuple[]"}],"internalType":"struct ISCFungibleTokens","name":"fungibleTokens","type":"tuple"},{"internalType":"bool","name":"adjustMinimumStorageDeposit","type":"bool"},{"components":[{"internalType":"ISCHname","name":"targetContract","type":"uint32"},{"internalType":"ISCHname","name":"entrypoint","type":"uint32"},{"components":[{"components":[{"internalType":"bytes","name":"key","type":"bytes"},{"internalType":"bytes","name":"value","type":"bytes"}],"internalType":"struct ISCDictItem[]","name":"items","type":"tuple[]"}],"internalType":"struct ISCDict","name":"params","type":"tuple"},{"components":[{"internalType":"uint64","name":"baseTokens","type":"uint64"},{"components":[{"components":[{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct NativeTokenID","name":"ID","type":"tuple"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct NativeToken[]","name":"tokens","type":"tuple[]"},{"internalType":"NFTID[]","name":"nfts","type":"bytes32[]"}],"internalType":"struct ISCAllowance","name":"allowance","type":"tuple"},{"internalType":"uint64","name":"gasBudget","type":"uint64"}],"internalType":"struct ISCSendMetadata","name":"metadata","type":"tuple"},{"components":[{"internalType":"int64","name":"timelock","type":"int64"},{"components":[{"internalType":"int64","name":"time","type":"int64"},{"components":[{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct L1Address","name":"returnAddress","type":"tuple"}],"internalType":"struct ISCExpiration","name":"expiration","type":"tuple"}],"internalType":"struct ISCSendOptions","name":"sendOptions","type":"tuple"}],"name":"send","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct L1Address","name":"targetAddress","type":"tuple"},{"components":[{"internalType":"uint64","name":"baseTokens","type":"uint64"},{"components":[{"components":[{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct NativeTokenID","name":"ID","type":"tuple"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct NativeToken[]","name":"tokens","type":"tuple[]"}],"internalType":"struct ISCFungibleTokens","name":"fungibleTokens","type":"tuple"},{"internalType":"NFTID","name":"id","type":"bytes32"},{"internalType":"bool","name":"adjustMinimumStorageDeposit","type":"bool"},{"components":[{"internalType":"ISCHname","name":"targetContract","type":"uint32"},{"internalType":"ISCHname","name":"entrypoint","type":"uint32"},{"components":[{"components":[{"internalType":"bytes","name":"key","type":"bytes"},{"internalType":"bytes","name":"value","type":"bytes"}],"internalType":"struct ISCDictItem[]","name":"items","type":"tuple[]"}],"internalType":"struct ISCDict","name":"params","type":"tuple"},{"components":[{"internalType":"uint64","name":"baseTokens","type":"uint64"},{"components":[{"components":[{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct NativeTokenID","name":"ID","type":"tuple"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct NativeToken[]","name":"tokens","type":"tuple[]"},{"internalType":"NFTID[]","name":"nfts","type":"bytes32[]"}],"internalType":"struct ISCAllowance","name":"allowance","type":"tuple"},{"internalType":"uint64","name":"gasBudget","type":"uint64"}],"internalType":"struct ISCSendMetadata","name":"metadata","type":"tuple"},{"components":[{"internalType":"int64","name":"timelock","type":"int64"},{"components":[{"internalType":"int64","name":"time","type":"int64"},{"components":[{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct L1Address","name":"returnAddress","type":"tuple"}],"internalType":"struct ISCExpiration","name":"expiration","type":"tuple"}],"internalType":"struct ISCSendOptions","name":"sendOptions","type":"tuple"}],"name":"sendAsNFT","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"},{"components":[{"internalType":"uint64","name":"baseTokens","type":"uint64"},{"components":[{"components":[{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct NativeTokenID","name":"ID","type":"tuple"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct NativeToken[]","name":"tokens","type":"tuple[]"},{"internalType":"NFTID[]","name":"nfts","type":"bytes32[]"}],"internalType":"struct ISCAllowance","name":"allowance","type":"tuple"}],"name":"takeAllowedFunds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"s","type":"string"}],"name":"triggerEvent","outputs":[],"stateMutability":"nonpayable","type":"function"}] \ No newline at end of file +[{"inputs":[{"internalType":"address","name":"target","type":"address"},{"components":[{"internalType":"uint64","name":"baseTokens","type":"uint64"},{"components":[{"components":[{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct NativeTokenID","name":"ID","type":"tuple"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct NativeToken[]","name":"tokens","type":"tuple[]"},{"internalType":"NFTID[]","name":"nfts","type":"bytes32[]"}],"internalType":"struct ISCAllowance","name":"allowance","type":"tuple"}],"name":"allow","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"ISCHname","name":"contractHname","type":"uint32"},{"internalType":"ISCHname","name":"entryPoint","type":"uint32"},{"components":[{"components":[{"internalType":"bytes","name":"key","type":"bytes"},{"internalType":"bytes","name":"value","type":"bytes"}],"internalType":"struct ISCDictItem[]","name":"items","type":"tuple[]"}],"internalType":"struct ISCDict","name":"params","type":"tuple"},{"components":[{"internalType":"uint64","name":"baseTokens","type":"uint64"},{"components":[{"components":[{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct NativeTokenID","name":"ID","type":"tuple"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct NativeToken[]","name":"tokens","type":"tuple[]"},{"internalType":"NFTID[]","name":"nfts","type":"bytes32[]"}],"internalType":"struct ISCAllowance","name":"allowance","type":"tuple"}],"name":"call","outputs":[{"components":[{"components":[{"internalType":"bytes","name":"key","type":"bytes"},{"internalType":"bytes","name":"value","type":"bytes"}],"internalType":"struct ISCDictItem[]","name":"items","type":"tuple[]"}],"internalType":"struct ISCDict","name":"","type":"tuple"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"ISCHname","name":"contractHname","type":"uint32"},{"internalType":"ISCHname","name":"entryPoint","type":"uint32"},{"components":[{"components":[{"internalType":"bytes","name":"key","type":"bytes"},{"internalType":"bytes","name":"value","type":"bytes"}],"internalType":"struct ISCDictItem[]","name":"items","type":"tuple[]"}],"internalType":"struct ISCDict","name":"params","type":"tuple"}],"name":"callView","outputs":[{"components":[{"components":[{"internalType":"bytes","name":"key","type":"bytes"},{"internalType":"bytes","name":"value","type":"bytes"}],"internalType":"struct ISCDictItem[]","name":"items","type":"tuple[]"}],"internalType":"struct ISCDict","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"}],"name":"getAllowance","outputs":[{"components":[{"internalType":"uint64","name":"baseTokens","type":"uint64"},{"components":[{"components":[{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct NativeTokenID","name":"ID","type":"tuple"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct NativeToken[]","name":"tokens","type":"tuple[]"},{"internalType":"NFTID[]","name":"nfts","type":"bytes32[]"}],"internalType":"struct ISCAllowance","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"getAllowanceFrom","outputs":[{"components":[{"internalType":"uint64","name":"baseTokens","type":"uint64"},{"components":[{"components":[{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct NativeTokenID","name":"ID","type":"tuple"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct NativeToken[]","name":"tokens","type":"tuple[]"},{"internalType":"NFTID[]","name":"nfts","type":"bytes32[]"}],"internalType":"struct ISCAllowance","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"target","type":"address"}],"name":"getAllowanceTo","outputs":[{"components":[{"internalType":"uint64","name":"baseTokens","type":"uint64"},{"components":[{"components":[{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct NativeTokenID","name":"ID","type":"tuple"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct NativeToken[]","name":"tokens","type":"tuple[]"},{"internalType":"NFTID[]","name":"nfts","type":"bytes32[]"}],"internalType":"struct ISCAllowance","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getBaseTokenProperties","outputs":[{"components":[{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"tickerSymbol","type":"string"},{"internalType":"uint8","name":"decimals","type":"uint8"},{"internalType":"uint256","name":"totalSupply","type":"uint256"}],"internalType":"struct ISCTokenProperties","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getChainID","outputs":[{"internalType":"ISCChainID","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getChainOwnerID","outputs":[{"components":[{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct ISCAgentID","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getEntropy","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"NFTID","name":"id","type":"bytes32"}],"name":"getNFTData","outputs":[{"components":[{"internalType":"NFTID","name":"ID","type":"bytes32"},{"components":[{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct L1Address","name":"issuer","type":"tuple"},{"internalType":"bytes","name":"metadata","type":"bytes"}],"internalType":"struct ISCNFT","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getRequestID","outputs":[{"components":[{"internalType":"ISCTransactionID","name":"transactionID","type":"bytes32"},{"internalType":"uint16","name":"transactionOutputIndex","type":"uint16"}],"internalType":"struct ISCRequestID","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getSenderAccount","outputs":[{"components":[{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct ISCAgentID","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTimestampUnixSeconds","outputs":[{"internalType":"int64","name":"","type":"int64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"s","type":"string"}],"name":"hn","outputs":[{"internalType":"ISCHname","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"s","type":"string"}],"name":"print","outputs":[],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"string","name":"s","type":"string"}],"name":"registerError","outputs":[{"internalType":"ISCError","name":"","type":"uint16"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct L1Address","name":"targetAddress","type":"tuple"},{"components":[{"internalType":"uint64","name":"baseTokens","type":"uint64"},{"components":[{"components":[{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct NativeTokenID","name":"ID","type":"tuple"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct NativeToken[]","name":"tokens","type":"tuple[]"}],"internalType":"struct ISCFungibleTokens","name":"fungibleTokens","type":"tuple"},{"internalType":"bool","name":"adjustMinimumStorageDeposit","type":"bool"},{"components":[{"internalType":"ISCHname","name":"targetContract","type":"uint32"},{"internalType":"ISCHname","name":"entrypoint","type":"uint32"},{"components":[{"components":[{"internalType":"bytes","name":"key","type":"bytes"},{"internalType":"bytes","name":"value","type":"bytes"}],"internalType":"struct ISCDictItem[]","name":"items","type":"tuple[]"}],"internalType":"struct ISCDict","name":"params","type":"tuple"},{"components":[{"internalType":"uint64","name":"baseTokens","type":"uint64"},{"components":[{"components":[{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct NativeTokenID","name":"ID","type":"tuple"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct NativeToken[]","name":"tokens","type":"tuple[]"},{"internalType":"NFTID[]","name":"nfts","type":"bytes32[]"}],"internalType":"struct ISCAllowance","name":"allowance","type":"tuple"},{"internalType":"uint64","name":"gasBudget","type":"uint64"}],"internalType":"struct ISCSendMetadata","name":"metadata","type":"tuple"},{"components":[{"internalType":"int64","name":"timelock","type":"int64"},{"components":[{"internalType":"int64","name":"time","type":"int64"},{"components":[{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct L1Address","name":"returnAddress","type":"tuple"}],"internalType":"struct ISCExpiration","name":"expiration","type":"tuple"}],"internalType":"struct ISCSendOptions","name":"sendOptions","type":"tuple"}],"name":"send","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct L1Address","name":"targetAddress","type":"tuple"},{"components":[{"internalType":"uint64","name":"baseTokens","type":"uint64"},{"components":[{"components":[{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct NativeTokenID","name":"ID","type":"tuple"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct NativeToken[]","name":"tokens","type":"tuple[]"}],"internalType":"struct ISCFungibleTokens","name":"fungibleTokens","type":"tuple"},{"internalType":"NFTID","name":"id","type":"bytes32"},{"internalType":"bool","name":"adjustMinimumStorageDeposit","type":"bool"},{"components":[{"internalType":"ISCHname","name":"targetContract","type":"uint32"},{"internalType":"ISCHname","name":"entrypoint","type":"uint32"},{"components":[{"components":[{"internalType":"bytes","name":"key","type":"bytes"},{"internalType":"bytes","name":"value","type":"bytes"}],"internalType":"struct ISCDictItem[]","name":"items","type":"tuple[]"}],"internalType":"struct ISCDict","name":"params","type":"tuple"},{"components":[{"internalType":"uint64","name":"baseTokens","type":"uint64"},{"components":[{"components":[{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct NativeTokenID","name":"ID","type":"tuple"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct NativeToken[]","name":"tokens","type":"tuple[]"},{"internalType":"NFTID[]","name":"nfts","type":"bytes32[]"}],"internalType":"struct ISCAllowance","name":"allowance","type":"tuple"},{"internalType":"uint64","name":"gasBudget","type":"uint64"}],"internalType":"struct ISCSendMetadata","name":"metadata","type":"tuple"},{"components":[{"internalType":"int64","name":"timelock","type":"int64"},{"components":[{"internalType":"int64","name":"time","type":"int64"},{"components":[{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct L1Address","name":"returnAddress","type":"tuple"}],"internalType":"struct ISCExpiration","name":"expiration","type":"tuple"}],"internalType":"struct ISCSendOptions","name":"sendOptions","type":"tuple"}],"name":"sendAsNFT","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"},{"components":[{"internalType":"uint64","name":"baseTokens","type":"uint64"},{"components":[{"components":[{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct NativeTokenID","name":"ID","type":"tuple"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct NativeToken[]","name":"tokens","type":"tuple[]"},{"internalType":"NFTID[]","name":"nfts","type":"bytes32[]"}],"internalType":"struct ISCAllowance","name":"allowance","type":"tuple"}],"name":"takeAllowedFunds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"s","type":"string"}],"name":"triggerEvent","outputs":[],"stateMutability":"nonpayable","type":"function"}] \ No newline at end of file diff --git a/packages/vm/core/evm/iscmagic/ISC.sol b/packages/vm/core/evm/iscmagic/ISC.sol index 8ea0839ece..d0accf81be 100644 --- a/packages/vm/core/evm/iscmagic/ISC.sol +++ b/packages/vm/core/evm/iscmagic/ISC.sol @@ -30,6 +30,9 @@ interface ISC { // Get the amount of funds currently allowed by the caller to the given address function getAllowanceTo(address target) external view returns (ISCAllowance memory); + // Get the amount of funds currently allowed between the given addresses + function getAllowance(address from, address to) external view returns (ISCAllowance memory); + // Send an on-ledger request (or a regular transaction to any L1 address). // The specified `fungibleTokens` are transferred from the caller's // L2 account to the `evm` core contract's account. @@ -75,12 +78,19 @@ interface ISC { // Get the timestamp of the ISC block (seconds since UNIX epoch) function getTimestampUnixSeconds() external view returns (int64); - // Get an ISC contract's hname given its instance name + // Get an ISC contract's hname given its instance name function hn(string memory s) external view returns (ISCHname); + + // Get the properties of the ISC base token + function getBaseTokenProperties() external view returns (ISCTokenProperties memory); + + // Print something to the console (will only work when debugging contracts with Solo) + function print(string memory s) external pure; } // Every ISC chain is initialized with an instance of the Magic contract at address 0x1074 -ISC constant isc = ISC(0x0000000000000000000000000000000000001074); +uint256 constant ISC_ADDRESS = 0x1074; +ISC constant isc = ISC(address(uint160(ISC_ADDRESS))); // An L1 IOTA address struct L1Address { @@ -182,3 +192,11 @@ type ISCError is uint16; // When reverting with VMError, the ISC receipt will include the given ISC error code. // See [registerError]. error VMError(ISCError); + +// Properties of an ISC base/native token +struct ISCTokenProperties { + string name; + string tickerSymbol; + uint8 decimals; + uint256 totalSupply; +} diff --git a/packages/vm/core/evm/iscmagic/ISCLib.sol b/packages/vm/core/evm/iscmagic/ISCLib.sol new file mode 100644 index 0000000000..d7c59d543f --- /dev/null +++ b/packages/vm/core/evm/iscmagic/ISCLib.sol @@ -0,0 +1,53 @@ +// Copyright 2020 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +pragma solidity >=0.8.11; + +import "@iscmagic/ISC.sol"; + +uint8 constant AgentIDKindEthereumAddress = 3; + +library ISCLib { + // Get the L2 balance of an account + function getL2BalanceBaseTokens(ISCAgentID memory agentID) internal view returns (uint64) { + ISCDict memory params; + params.items = new ISCDictItem[](1); + params.items[0].key = bytes("a"); + params.items[0].value = agentID.data; + + ISCDict memory r = isc.callView(isc.hn("accounts"), isc.hn("balanceBaseToken"), params); + + for (uint i = 0; i < r.items.length; i++) { + if (r.items[i].key.length == 1 && r.items[i].key[0] == 'B') { + return decodeUint64(r.items[i].value); + } + } + revert("something went wrong"); + } + + function bytesToUint(bytes memory b) internal pure returns (uint256){ + uint256 number; + for(uint i = 0; i < b.length; i++){ + number = number + uint(uint8(b[i])) * (2**(8*i)); + } + return number; + } + + + // Decode 4 bytes little-endian to uint64 + function decodeUint64(bytes memory b) internal pure returns (uint64) { + require(b.length == 8, "decodeUint64: expected 8 bytes"); + return uint64(bytesToUint(b)); + } + + function newEthereumAgentID(address addr) internal pure returns (ISCAgentID memory) { + bytes memory addrBytes = abi.encodePacked(addr); + ISCAgentID memory r; + r.data = new bytes(1+addrBytes.length); + r.data[0] = bytes1(AgentIDKindEthereumAddress); + for (uint i = 0; i < addrBytes.length; i++) { + r.data[i+1] = addrBytes[i]; + } + return r; + } +} diff --git a/packages/vm/core/evm/iscmagic/ISCPrivileged.abi b/packages/vm/core/evm/iscmagic/ISCPrivileged.abi new file mode 100644 index 0000000000..57ef4cea98 --- /dev/null +++ b/packages/vm/core/evm/iscmagic/ISCPrivileged.abi @@ -0,0 +1 @@ +[{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"components":[{"internalType":"uint64","name":"baseTokens","type":"uint64"},{"components":[{"components":[{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct NativeTokenID","name":"ID","type":"tuple"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct NativeToken[]","name":"tokens","type":"tuple[]"},{"internalType":"NFTID[]","name":"nfts","type":"bytes32[]"}],"internalType":"struct ISCAllowance","name":"allowance","type":"tuple"}],"name":"addToAllowance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"components":[{"internalType":"uint64","name":"baseTokens","type":"uint64"},{"components":[{"components":[{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct NativeTokenID","name":"ID","type":"tuple"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct NativeToken[]","name":"tokens","type":"tuple[]"},{"internalType":"NFTID[]","name":"nfts","type":"bytes32[]"}],"internalType":"struct ISCAllowance","name":"allowance","type":"tuple"}],"name":"moveAllowedFunds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"receiver","type":"address"},{"components":[{"internalType":"uint64","name":"baseTokens","type":"uint64"},{"components":[{"components":[{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct NativeTokenID","name":"ID","type":"tuple"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct NativeToken[]","name":"tokens","type":"tuple[]"},{"internalType":"NFTID[]","name":"nfts","type":"bytes32[]"}],"internalType":"struct ISCAllowance","name":"allowance","type":"tuple"}],"name":"moveBetweenAccounts","outputs":[],"stateMutability":"nonpayable","type":"function"}] \ No newline at end of file diff --git a/packages/vm/core/evm/iscmagic/ISCPrivileged.sol b/packages/vm/core/evm/iscmagic/ISCPrivileged.sol new file mode 100644 index 0000000000..780b4cb6c2 --- /dev/null +++ b/packages/vm/core/evm/iscmagic/ISCPrivileged.sol @@ -0,0 +1,14 @@ +// Copyright 2020 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +pragma solidity >=0.8.11; + +import "@iscmagic/ISC.sol"; + +// The ISC magic contract has some extra methods not included in the standard ISC interface: +// (only callable from privileged contracts) +interface ISCPrivileged { + function moveBetweenAccounts(address sender, address receiver, ISCAllowance memory allowance) external; + function addToAllowance(address from, address to, ISCAllowance memory allowance) external; + function moveAllowedFunds(address from, address to, ISCAllowance memory allowance) external; +} diff --git a/packages/vm/core/evm/iscmagic/embed.go b/packages/vm/core/evm/iscmagic/embed.go index 4d555de119..2eeeb50ac1 100644 --- a/packages/vm/core/evm/iscmagic/embed.go +++ b/packages/vm/core/evm/iscmagic/embed.go @@ -5,9 +5,14 @@ package iscmagic import ( _ "embed" + "encoding/binary" + "strings" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/vm" ) -// If you change ISC.sol, you must recompile. You will need +// If you change any of the .sol files, you must recompile. You will need // the `solc` binary installed in your system. Then, simply run `go generate` // in this directory. @@ -16,3 +21,27 @@ var ( //go:embed ISC.abi ABI string ) + +//go:generate sh -c "solc --abi --overwrite @iscmagic=`realpath .` ISCPrivileged.sol -o ." +var ( + //go:embed ISCPrivileged.abi + PrivilegedABI string +) + +//go:generate sh -c "solc --abi --bin-runtime --overwrite @iscmagic=`realpath .` ERC20BaseTokens.sol -o ." +var ( + //go:embed ERC20BaseTokens.abi + ERC20BaseTokensABI string + //go:embed ERC20BaseTokens.bin-runtime + erc20BaseRuntimeBytecodeHex string + ERC20BaseTokensRuntimeBytecode = common.FromHex(strings.TrimSpace(erc20BaseRuntimeBytecodeHex)) +) + +var ERC20BaseTokensAddress = iscAddressPlusOne() + +func iscAddressPlusOne() common.Address { + n := binary.BigEndian.Uint64(vm.ISCAddress.Bytes()[common.AddressLength-8:]) + 1 + var ret common.Address + binary.BigEndian.PutUint64(ret[common.AddressLength-8:], n) + return ret +} diff --git a/packages/vm/core/evm/iscmagic/types.go b/packages/vm/core/evm/iscmagic/types.go index 59a007a050..603e9a551d 100644 --- a/packages/vm/core/evm/iscmagic/types.go +++ b/packages/vm/core/evm/iscmagic/types.go @@ -386,3 +386,10 @@ func (i *ISCSendOptions) Unwrap() isc.SendOptions { return ret } + +type ISCTokenProperties struct { + Name string + TickerSymbol string + Decimals uint8 + TotalSupply *big.Int +}