From 764e151489d2fc32a25acc70b07eaf7bada455c5 Mon Sep 17 00:00:00 2001 From: Maddiaa0 <47148561+Maddiaa0@users.noreply.github.com> Date: Sat, 8 Jul 2023 19:32:26 +0000 Subject: [PATCH 1/3] feat: initial 0.3.2 support --- .gitmodules | 1 + lib/foundry-huff | 2 +- ...bcbtcjlsalfjomvpsarxoeqmfengiahvOwned.huff | 106 + ...jnrubnscbigchdduxlqllnuupOnlyContract.huff | 26 + ...gjqqvwuwnofsrtwqcnwpvegncntNonPayable.huff | 27 + ...mmmqoxevqxajvrhicbguifoRolesAuthority.huff | 314 +++ ...fjpzjdeotdemryddmmyhqlqRolesAuthority.huff | 314 +++ ...orycdmcbstquohvoehulrstRolesAuthority.huff | 314 +++ ...rlgdtvsadoebscpgqfqrmgtsohzNonPayable.huff | 27 + ...vmqkfekoylppiiwxfdjnbfnRolesAuthority.huff | 314 +++ ...qnjmdgxfwtecsggrrzgqbnqyqOnlyContract.huff | 26 + ...zvezglymjookpccrxwupfpflpekwphopOwned.huff | 106 + ...bkprxxmslvmupkpkwuxxniuwscdqqrnArrays.huff | 121 ++ ...wgxfmgyfyneyghrepikbyjmyskqxskHashmap.huff | 317 +++ ...xhhzaaidyagiaawzeyxpvkgxcxwtgqHashmap.huff | 317 +++ ...lwkvhrrmofongwpxrjtworcwgnfqpxluBytes.huff | 349 ++++ ...wmivzahxlhrjuiphjztstbcaymhckevArrays.huff | 121 ++ ...wvnaxkgsgqemkcqoqqvognrxtldwtppxBytes.huff | 349 ++++ ..._agffsybhummgrdmhvrzqoxrnkhupycfeMath.huff | 319 +++ ...xtadnkjdmxsyyimfngsleoolwhcqtSafeMath.huff | 153 ++ ...nyeazoevkblfjmhdomwtqwoFixedPointMath.huff | 1093 ++++++++++ ...opkbndglbmvjbzlrpyrrzphnrTrigonometry.huff | 218 ++ ...edbspprhymlfrgxlfepgepcrvTrigonometry.huff | 218 ++ ...uxpdpeuvffbywnubcftdxsyFixedPointMath.huff | 1093 ++++++++++ ..._qvmazraiuhrdvuoecpapxakdrzpwpmuqMath.huff | 319 +++ ...imbuhetstepqivcpdmtxszazlqpnnSafeMath.huff | 153 ++ ...dwsqmdvneonbcfprxtzfbmhkuExampleClone.huff | 77 + ...edeoorfkumjbbbagtfehbslnhExampleClone.huff | 77 + ...jajsmfrshnyoafedbhvmybxcfExampleClone.huff | 77 + ...qgllfjrqfvrmjmhzvpeefnmpcExampleClone.huff | 77 + ...dlyztnvsbkuhzfucpimehhtdLogisticVRGDA.huff | 77 + ...nwnrmtgswdmaharirrkhhznvgtLinearVRGDA.huff | 57 + ...lavwmvnufiarmtrrvilwbhnhmfuxofvClones.huff | 213 ++ ...rlnsihsjssxbghxugniamuyipERC1967Proxy.huff | 158 ++ ...lwhmiuazdwnqpgoxdvgcsfczvtfymagClones.huff | 213 ++ ...blgmhozyfyviczblaggscrgixERC1967Proxy.huff | 158 ++ ...fztznazwowexesrohcdykwsmvfkclmuyERC20.huff | 676 +++++++ ...olyemymwzenpqjpuukwgitehudafctpwERC20.huff | 676 +++++++ ...qsfkvbhimsywiqwbdlilqoxezxnqvipERC721.huff | 787 ++++++++ ...pvmgiyjorautmnplhzvgjsaeubpvhbERC4626.huff | 859 ++++++++ ...vaewlzfkyljuiwoxdrktdnlhsuzsmbhERC721.huff | 787 ++++++++ ...gqnylgrbytfwvkvdnlnpcvxmcecsliERC4626.huff | 859 ++++++++ ...kbbusaspkdjqohbmhkbfmghcmmpksnCREATE3.huff | 177 ++ ...qwgufgegzhdrxxamgnvfwtnzJumpTableUtil.huff | 149 ++ ...fqjrpihtljpxmlgbwuzstqlMerkleProofLib.huff | 86 + ...ubbndjqnadwlvmuebjtdnnpdjprqConstants.huff | 1789 +++++++++++++++++ ...qdaprqvhayryuhporeghmzSafeTransferLib.huff | 202 ++ ...ctwgjphmybkljahoybtnldrrcpneywglECDSA.huff | 305 +++ ...wfcmbyyrjifcrrrqvnmskahrxtfwfPausable.huff | 131 ++ ...dolvqpolutctxhctjzvajsrpbtpqfvdlCalls.huff | 217 ++ ...medggubevwdmphskibtxMerkleDistributor.huff | 247 +++ ...rijckuxiernloalienlasrtffackConstants.huff | 1789 +++++++++++++++++ ...yomwxkixnogyzbecekrqolgmjnwpgibLibBit.huff | 267 +++ ...sfweqvmnghgiyyjyzxhruyzqbslBitPackLib.huff | 104 + ...blaazsrdhqxfgjsonhnpjloMerkleProofLib.huff | 86 + ...wzbaphyfhugpyejapdmpmaanfaqcTSOwnable.huff | 172 ++ ...byoimpybpmxmyrddbxuhherfeclBitPackLib.huff | 104 + ...tonvmuwvpsgnhyhrztoimrzkyqskTSOwnable.huff | 172 ++ ...zlramplmuvmnsgrxrurevmmugyklixkEthers.huff | 47 + ...trgmsogdgtpmxmtwqmpdocReentrancyGuard.huff | 127 ++ ...cylvhdduoakglqjyfagmmbgbJumpTableUtil.huff | 149 ++ ...xgytjvcjspqzqpxtbelyxicffhqxfrSSTORE2.huff | 132 ++ ...jwomkxvqpeatpkwmzsmvjaneohelmRefunded.huff | 97 + ...bfpunncyiouwtmltswyzljambbxxShuffling.huff | 68 + ...rpqdglcwrdylrneycegnebReentrancyGuard.huff | 127 ++ ...wyyoypwjyhbfuzsxxekolsbwxgwxsdSSTORE2.huff | 132 ++ ...pohrkhyvnxmaxjzqlkackypaopwtytiErrors.huff | 303 +++ ...suvrwjmqtxbpjcrrcoacbfeiivquShuffling.huff | 68 + ...bvbklotqjimwddbdrttqayfxbbmavfvLibBit.huff | 267 +++ ...qfzbthtrligkzrxhdcwizlbkonnnqqiyCalls.huff | 217 ++ ...cokotvnwlrlotlmzautjwxvsMulticallable.huff | 233 +++ ...ryraejdcasobgumhdtbwarjszpnlvasmECDSA.huff | 305 +++ ...fwvdxpickfrbtnbbaudfvqefkatoiRefunded.huff | 97 + ...osskvfeygpuobkhcslnvMerkleDistributor.huff | 247 +++ ...uhcelrjhrahufjtvdthjstmmMulticallable.huff | 233 +++ ...wdnvquznelrjppmvqtmvduSafeTransferLib.huff | 202 ++ ...bhvkcstcqznkwuhmkwwvrdjviacaricEthers.huff | 47 + ...mxfmambbznmfrsntcscmmocveeDateTimeLib.huff | 517 +++++ ...fnwunrsrlqxsbhtmizflbifjcrmxdqCREATE3.huff | 177 ++ ...wkphsyuihxlbouwaxpbkeiagInsertionSort.huff | 100 + ...pvqgkfupsuzejejufgqepcfpeyDateTimeLib.huff | 517 +++++ ...vhpaiggcjojltrdelmvtrrnvpcuusPausable.huff | 131 ++ ...msfvcgannmmwswbxlbvrttkmvnfxjsyErrors.huff | 303 +++ ...utylwrboumnhnihgplkcsjdrInsertionSort.huff | 100 + 84 files changed, 23484 insertions(+), 1 deletion(-) create mode 100644 src/auth/__TEMP__bcbtcjlsalfjomvpsarxoeqmfengiahvOwned.huff create mode 100644 src/auth/__TEMP__ecksuksjnrubnscbigchdduxlqllnuupOnlyContract.huff create mode 100644 src/auth/__TEMP__esiqrgjqqvwuwnofsrtwqcnwpvegncntNonPayable.huff create mode 100644 src/auth/__TEMP__jddsbmqfkmmmqoxevqxajvrhicbguifoRolesAuthority.huff create mode 100644 src/auth/__TEMP__nhzcwzdenfjpzjdeotdemryddmmyhqlqRolesAuthority.huff create mode 100644 src/auth/__TEMP__nmlzffubaorycdmcbstquohvoehulrstRolesAuthority.huff create mode 100644 src/auth/__TEMP__uebzhrlgdtvsadoebscpgqfqrmgtsohzNonPayable.huff create mode 100644 src/auth/__TEMP__zmjetucvgvmqkfekoylppiiwxfdjnbfnRolesAuthority.huff create mode 100644 src/auth/__TEMP__zqlaafiqnjmdgxfwtecsggrrzgqbnqyqOnlyContract.huff create mode 100644 src/auth/__TEMP__zvezglymjookpccrxwupfpflpekwphopOwned.huff create mode 100644 src/data-structures/__TEMP__dbkprxxmslvmupkpkwuxxniuwscdqqrnArrays.huff create mode 100644 src/data-structures/__TEMP__fvwgxfmgyfyneyghrepikbyjmyskqxskHashmap.huff create mode 100644 src/data-structures/__TEMP__jqxhhzaaidyagiaawzeyxpvkgxcxwtgqHashmap.huff create mode 100644 src/data-structures/__TEMP__lwkvhrrmofongwpxrjtworcwgnfqpxluBytes.huff create mode 100644 src/data-structures/__TEMP__swmivzahxlhrjuiphjztstbcaymhckevArrays.huff create mode 100644 src/data-structures/__TEMP__wvnaxkgsgqemkcqoqqvognrxtldwtppxBytes.huff create mode 100644 src/math/__TEMP__agffsybhummgrdmhvrzqoxrnkhupycfeMath.huff create mode 100644 src/math/__TEMP__gtvxtadnkjdmxsyyimfngsleoolwhcqtSafeMath.huff create mode 100644 src/math/__TEMP__hbpqkpduhnyeazoevkblfjmhdomwtqwoFixedPointMath.huff create mode 100644 src/math/__TEMP__ohdnimzopkbndglbmvjbzlrpyrrzphnrTrigonometry.huff create mode 100644 src/math/__TEMP__qakkodxedbspprhymlfrgxlfepgepcrvTrigonometry.huff create mode 100644 src/math/__TEMP__qnnyckotyuxpdpeuvffbywnubcftdxsyFixedPointMath.huff create mode 100644 src/math/__TEMP__qvmazraiuhrdvuoecpapxakdrzpwpmuqMath.huff create mode 100644 src/math/__TEMP__wqcimbuhetstepqivcpdmtxszazlqpnnSafeMath.huff create mode 100644 src/mechanisms/huff-clones/__TEMP__hvlmmbwdwsqmdvneonbcfprxtzfbmhkuExampleClone.huff create mode 100644 src/mechanisms/huff-clones/__TEMP__pgbwefuedeoorfkumjbbbagtfehbslnhExampleClone.huff create mode 100644 src/mechanisms/huff-clones/__TEMP__xhkqnmmjajsmfrshnyoafedbhvmybxcfExampleClone.huff create mode 100644 src/mechanisms/huff-clones/__TEMP__xpmxrssqgllfjrqfvrmjmhzvpeefnmpcExampleClone.huff create mode 100644 src/mechanisms/huff-vrgda/__TEMP__emehkakqdlyztnvsbkuhzfucpimehhtdLogisticVRGDA.huff create mode 100644 src/mechanisms/huff-vrgda/__TEMP__fldyysnwnrmtgswdmaharirrkhhznvgtLinearVRGDA.huff create mode 100644 src/proxies/__TEMP__flavwmvnufiarmtrrvilwbhnhmfuxofvClones.huff create mode 100644 src/proxies/__TEMP__klhwbuerlnsihsjssxbghxugniamuyipERC1967Proxy.huff create mode 100644 src/proxies/__TEMP__xlwhmiuazdwnqpgoxdvgcsfczvtfymagClones.huff create mode 100644 src/proxies/__TEMP__zgifhurblgmhozyfyviczblaggscrgixERC1967Proxy.huff create mode 100644 src/tokens/__TEMP__fztznazwowexesrohcdykwsmvfkclmuyERC20.huff create mode 100644 src/tokens/__TEMP__olyemymwzenpqjpuukwgitehudafctpwERC20.huff create mode 100644 src/tokens/__TEMP__oqsfkvbhimsywiqwbdlilqoxezxnqvipERC721.huff create mode 100644 src/tokens/__TEMP__tdpvmgiyjorautmnplhzvgjsaeubpvhbERC4626.huff create mode 100644 src/tokens/__TEMP__vvaewlzfkyljuiwoxdrktdnlhsuzsmbhERC721.huff create mode 100644 src/tokens/__TEMP__zxgqnylgrbytfwvkvdnlnpcvxmcecsliERC4626.huff create mode 100644 src/utils/__TEMP__ahkbbusaspkdjqohbmhkbfmghcmmpksnCREATE3.huff create mode 100644 src/utils/__TEMP__ajvxrvsbqwgufgegzhdrxxamgnvfwtnzJumpTableUtil.huff create mode 100644 src/utils/__TEMP__appuiqwhffqjrpihtljpxmlgbwuzstqlMerkleProofLib.huff create mode 100644 src/utils/__TEMP__avabubbndjqnadwlvmuebjtdnnpdjprqConstants.huff create mode 100644 src/utils/__TEMP__bnvxrcqsckqdaprqvhayryuhporeghmzSafeTransferLib.huff create mode 100644 src/utils/__TEMP__ctwgjphmybkljahoybtnldrrcpneywglECDSA.huff create mode 100644 src/utils/__TEMP__dabwfcmbyyrjifcrrrqvnmskahrxtfwfPausable.huff create mode 100644 src/utils/__TEMP__dolvqpolutctxhctjzvajsrpbtpqfvdlCalls.huff create mode 100644 src/utils/__TEMP__ejbyrnbkhzztmedggubevwdmphskibtxMerkleDistributor.huff create mode 100644 src/utils/__TEMP__epqcrijckuxiernloalienlasrtffackConstants.huff create mode 100644 src/utils/__TEMP__eyomwxkixnogyzbecekrqolgmjnwpgibLibBit.huff create mode 100644 src/utils/__TEMP__fipsesfweqvmnghgiyyjyzxhruyzqbslBitPackLib.huff create mode 100644 src/utils/__TEMP__flqjyauokblaazsrdhqxfgjsonhnpjloMerkleProofLib.huff create mode 100644 src/utils/__TEMP__fsghwzbaphyfhugpyejapdmpmaanfaqcTSOwnable.huff create mode 100644 src/utils/__TEMP__fvsgbbyoimpybpmxmyrddbxuhherfeclBitPackLib.huff create mode 100644 src/utils/__TEMP__gbfutonvmuwvpsgnhyhrztoimrzkyqskTSOwnable.huff create mode 100644 src/utils/__TEMP__gzlramplmuvmnsgrxrurevmmugyklixkEthers.huff create mode 100644 src/utils/__TEMP__hkejoojmditrgmsogdgtpmxmtwqmpdocReentrancyGuard.huff create mode 100644 src/utils/__TEMP__hutfgjhkcylvhdduoakglqjyfagmmbgbJumpTableUtil.huff create mode 100644 src/utils/__TEMP__iuxgytjvcjspqzqpxtbelyxicffhqxfrSSTORE2.huff create mode 100644 src/utils/__TEMP__kfkjwomkxvqpeatpkwmzsmvjaneohelmRefunded.huff create mode 100644 src/utils/__TEMP__kkfsbfpunncyiouwtmltswyzljambbxxShuffling.huff create mode 100644 src/utils/__TEMP__ldwwbkwihqrpqdglcwrdylrneycegnebReentrancyGuard.huff create mode 100644 src/utils/__TEMP__piwyyoypwjyhbfuzsxxekolsbwxgwxsdSSTORE2.huff create mode 100644 src/utils/__TEMP__ppohrkhyvnxmaxjzqlkackypaopwtytiErrors.huff create mode 100644 src/utils/__TEMP__prdtsuvrwjmqtxbpjcrrcoacbfeiivquShuffling.huff create mode 100644 src/utils/__TEMP__qbvbklotqjimwddbdrttqayfxbbmavfvLibBit.huff create mode 100644 src/utils/__TEMP__qfzbthtrligkzrxhdcwizlbkonnnqqiyCalls.huff create mode 100644 src/utils/__TEMP__rrvaaiimcokotvnwlrlotlmzautjwxvsMulticallable.huff create mode 100644 src/utils/__TEMP__ryraejdcasobgumhdtbwarjszpnlvasmECDSA.huff create mode 100644 src/utils/__TEMP__sjmfwvdxpickfrbtnbbaudfvqefkatoiRefunded.huff create mode 100644 src/utils/__TEMP__sqowhqjsqxheosskvfeygpuobkhcslnvMerkleDistributor.huff create mode 100644 src/utils/__TEMP__syuldunwuhcelrjhrahufjtvdthjstmmMulticallable.huff create mode 100644 src/utils/__TEMP__tvibuicjahwdnvquznelrjppmvqtmvduSafeTransferLib.huff create mode 100644 src/utils/__TEMP__ubhvkcstcqznkwuhmkwwvrdjviacaricEthers.huff create mode 100644 src/utils/__TEMP__vamkrwmxfmambbznmfrsntcscmmocveeDateTimeLib.huff create mode 100644 src/utils/__TEMP__vqfnwunrsrlqxsbhtmizflbifjcrmxdqCREATE3.huff create mode 100644 src/utils/__TEMP__wiecgaaxwkphsyuihxlbouwaxpbkeiagInsertionSort.huff create mode 100644 src/utils/__TEMP__wtgpdnpvqgkfupsuzejejufgqepcfpeyDateTimeLib.huff create mode 100644 src/utils/__TEMP__xllvhpaiggcjojltrdelmvtrrnvpcuusPausable.huff create mode 100644 src/utils/__TEMP__xmsfvcgannmmwswbxlbvrttkmvnfxjsyErrors.huff create mode 100644 src/utils/__TEMP__zzxsgvxvutylwrboumnhnihgplkcsjdrInsertionSort.huff diff --git a/.gitmodules b/.gitmodules index 1f2110ee..1d8468b9 100644 --- a/.gitmodules +++ b/.gitmodules @@ -7,3 +7,4 @@ [submodule "lib/foundry-huff"] path = lib/foundry-huff url = https://github.com/huff-language/foundry-huff + branch = md/evm-version-option diff --git a/lib/foundry-huff b/lib/foundry-huff index e6913157..f027ce6d 160000 --- a/lib/foundry-huff +++ b/lib/foundry-huff @@ -1 +1 @@ -Subproject commit e691315769147cffb6245536e039e590aed78455 +Subproject commit f027ce6d6f64e553a023f0daa7747ebd70edbeaa diff --git a/src/auth/__TEMP__bcbtcjlsalfjomvpsarxoeqmfengiahvOwned.huff b/src/auth/__TEMP__bcbtcjlsalfjomvpsarxoeqmfengiahvOwned.huff new file mode 100644 index 00000000..09840cc6 --- /dev/null +++ b/src/auth/__TEMP__bcbtcjlsalfjomvpsarxoeqmfengiahvOwned.huff @@ -0,0 +1,106 @@ + +#define macro CONSTRUCTOR() = takes (0) returns (0) { + OWNED_CONSTRUCTOR() +} + +#define macro MAIN() = takes (0) returns (0) { + pc calldataload 0xe0 shr + OWNED_MAIN() + 0x00 dup1 revert +} + + +/// @title Owned +/// @notice SPDX-License-Identifier: MIT +/// @author asnared +/// @notice An single owner authorization module +/// @notice Adapted from + +// Interface +#define function setOwner(address) nonpayable returns () +#define function owner() view returns (address) + +// Events +#define event OwnerUpdated(address indexed user, address indexed newOwner) + +// Storage Slots +#define constant OWNER = FREE_STORAGE_POINTER() + +// CONSTRUCTOR +#define macro OWNED_CONSTRUCTOR() = takes (0) returns (0) { + // Copy the owner into memory + 0x20 // [size] - byte size to copy + 0x20 codesize sub // [offset, size] - offset in the code to copy from + 0x00 // [mem, offset, size] - offset in memory to copy to + codecopy // [] + + // Set the new owner + 0x00 mload // [owner] + dup1 // [owner, owner] + [OWNER] // [OWNER, owner, owner] + sstore // [owner] + + // Emit the owner updated event + caller // [from, owner] + __EVENT_HASH(OwnerUpdated) // [sig, from, owner] + 0x00 0x00 // [0, 0, sig, from, owner] + log3 // [] +} + +/// @notice Only Owner Modifier +#define macro IS_OWNER() = takes (0) returns (0) { + caller // [msg.sender] + [OWNER] sload // [owner, msg.sender] + eq authed jumpi // [authed] + + // Revert otherwise + 0x00 0x00 revert + + authed: +} + +/// @notice Set the Owner +/// @param {owner} [address] - The new owner +#define macro SET_OWNER() = takes (0) returns (0) { + // Check that the caller is authorized + IS_OWNER() + + // Set the new owner + 0x04 calldataload // [newOwner] + dup1 // [newOwner, newOwner] + [OWNER] sstore // [newOwner] + + // Emit the owner updated event + caller // [from, newOwner] + __EVENT_HASH(OwnerUpdated) // [sig, from, newOwner] + 0x00 0x00 // [0, 32, sig, from, newOwner] + log3 // [] + + stop +} + +/// @notice Get the owner of the contract +/// @return {owner} [address] - The owner of the contract +#define macro OWNER() = takes (0) returns (0) { + [OWNER] sload // [owner] + 0x00 mstore // [] + 0x20 0x00 return +} + +/// @notice Main Function Dispatcher +#define macro OWNED_MAIN() = takes (1) returns (1) { + // Input Stack: [function_selector] + + dup1 __FUNC_SIG(setOwner) eq set_owner jumpi + dup1 __FUNC_SIG(owner) eq owner jumpi + + // Bubble up to parent macro + no_match jump + + set_owner: + SET_OWNER() + owner: + OWNER() + + no_match: +} \ No newline at end of file diff --git a/src/auth/__TEMP__ecksuksjnrubnscbigchdduxlqllnuupOnlyContract.huff b/src/auth/__TEMP__ecksuksjnrubnscbigchdduxlqllnuupOnlyContract.huff new file mode 100644 index 00000000..20350e76 --- /dev/null +++ b/src/auth/__TEMP__ecksuksjnrubnscbigchdduxlqllnuupOnlyContract.huff @@ -0,0 +1,26 @@ +#define macro MAIN() = takes(0) returns(0) { + ONLY_CONTRACT() + 0x00 0x00 log0 // anonymous log + 0x01 0x00 mstore + 0x20 0x00 return +} + + +/// @title OnlyContract +/// @notice SPDX-License-Identifier: MIT +/// @author asnared +/// @notice Reverts if the caller is not a contract with a tx.origin check. + +/// @notice Reverts if the caller is not a contract using tx.origin. +/// @dev WARNING: This is an anti-pattern and prevents interoperability. +/// Additionally, this will become ineffective once either EIP-2938 OR EIP-4337 account abstraction's are implemented. +/// EIP-3074 is another concern as it essentially allows users to delegate control of an EOA to a contract. +/// Additionally, users of wallets like argent, authereum and gnosis multi-sigs are able to "bypass" this access control. +#define macro ONLY_CONTRACT() = takes (0) returns (0) { + caller // [msg.sender] + origin // [tx.origin, msg.sender] + eq iszero // [tx.origin != msg.sender] + continue jumpi // [] + 0x00 dup1 revert // [] + continue: +} diff --git a/src/auth/__TEMP__esiqrgjqqvwuwnofsrtwqcnwpvegncntNonPayable.huff b/src/auth/__TEMP__esiqrgjqqvwuwnofsrtwqcnwpvegncntNonPayable.huff new file mode 100644 index 00000000..922ee3d6 --- /dev/null +++ b/src/auth/__TEMP__esiqrgjqqvwuwnofsrtwqcnwpvegncntNonPayable.huff @@ -0,0 +1,27 @@ +#define macro MAIN() = takes(0) returns(0) { + NON_PAYABLE() + 0x00 0x00 log0 // anonymous log + 0x01 0x00 mstore + 0x20 0x00 return +} + + +/// @title Non Payable +/// @notice SPDX-License-Identifier: MIT +/// @author asnared +/// @notice Simple macro to revert if a call has a value + +#include "../utils/Errors.huff" + +// "NON_PAYABLE" Revert Message String +#define constant NON_PAYABLE_ERROR = 0xb4e4f4e5f50415941424c45000000000000000000000000000000000000000000 +#define constant NON_PAYABLE_LENGTH = 0x0b + +/// @notice Reverts if the call has a non-zero value +/// @notice Reverts with message "NON_PAYABLE" +#define macro NON_PAYABLE() = takes (0) returns (0) { + [NON_PAYABLE_ERROR] // ["NON_PAYABLE"] + [NON_PAYABLE_LENGTH] // [11 (length), "NON_PAYABLE"] + callvalue iszero // [msg.value == 0, 11 (length), "NON_PAYABLE"] + REQUIRE() // [] +} diff --git a/src/auth/__TEMP__jddsbmqfkmmmqoxevqxajvrhicbguifoRolesAuthority.huff b/src/auth/__TEMP__jddsbmqfkmmmqoxevqxajvrhicbguifoRolesAuthority.huff new file mode 100644 index 00000000..a9f4551e --- /dev/null +++ b/src/auth/__TEMP__jddsbmqfkmmmqoxevqxajvrhicbguifoRolesAuthority.huff @@ -0,0 +1,314 @@ + +#define macro CONSTRUCTOR() = takes (0) returns (0) { + AUTH_CONSTRUCTOR() +} + +#define macro MAIN() = takes (0) returns (0) { + pc calldataload 0xe0 shr + ROLES_AUTHORITY_MAIN() + 0x00 dup1 revert +} + + +/// @title Roles Authority +/// @notice SPDX-License-Identifier: MIT +/// @author asnared +/// @notice A Role based Authority that supports up to 256 roles +/// @notice Adapted from Solmate ( +/// @notice A Role based Authority that supports up to 256 roles +/// @notice Adapted from Solmate ( +/// @notice A Role based Authority that supports up to 256 roles +/// @notice Adapted from Solmate ( +/// @notice Simple macro to revert if a call has a value + +#include "../utils/Errors.huff" + +// "NON_PAYABLE" Revert Message String +#define constant NON_PAYABLE_ERROR = 0xb4e4f4e5f50415941424c45000000000000000000000000000000000000000000 +#define constant NON_PAYABLE_LENGTH = 0x0b + +/// @notice Reverts if the call has a non-zero value +/// @notice Reverts with message "NON_PAYABLE" +#define macro NON_PAYABLE() = takes (0) returns (0) { + [NON_PAYABLE_ERROR] // ["NON_PAYABLE"] + [NON_PAYABLE_LENGTH] // [11 (length), "NON_PAYABLE"] + callvalue iszero // [msg.value == 0, 11 (length), "NON_PAYABLE"] + REQUIRE() // [] +} diff --git a/src/auth/__TEMP__zmjetucvgvmqkfekoylppiiwxfdjnbfnRolesAuthority.huff b/src/auth/__TEMP__zmjetucvgvmqkfekoylppiiwxfdjnbfnRolesAuthority.huff new file mode 100644 index 00000000..a9f4551e --- /dev/null +++ b/src/auth/__TEMP__zmjetucvgvmqkfekoylppiiwxfdjnbfnRolesAuthority.huff @@ -0,0 +1,314 @@ + +#define macro CONSTRUCTOR() = takes (0) returns (0) { + AUTH_CONSTRUCTOR() +} + +#define macro MAIN() = takes (0) returns (0) { + pc calldataload 0xe0 shr + ROLES_AUTHORITY_MAIN() + 0x00 dup1 revert +} + + +/// @title Roles Authority +/// @notice SPDX-License-Identifier: MIT +/// @author asnared +/// @notice A Role based Authority that supports up to 256 roles +/// @notice Adapted from Solmate ( +/// @notice Reverts if the caller is not a contract with a tx.origin check. + +/// @notice Reverts if the caller is not a contract using tx.origin. +/// @dev WARNING: This is an anti-pattern and prevents interoperability. +/// Additionally, this will become ineffective once either EIP-2938 OR EIP-4337 account abstraction's are implemented. +/// EIP-3074 is another concern as it essentially allows users to delegate control of an EOA to a contract. +/// Additionally, users of wallets like argent, authereum and gnosis multi-sigs are able to "bypass" this access control. +#define macro ONLY_CONTRACT() = takes (0) returns (0) { + caller // [msg.sender] + origin // [tx.origin, msg.sender] + eq iszero // [tx.origin != msg.sender] + continue jumpi // [] + 0x00 dup1 revert // [] + continue: +} diff --git a/src/auth/__TEMP__zvezglymjookpccrxwupfpflpekwphopOwned.huff b/src/auth/__TEMP__zvezglymjookpccrxwupfpflpekwphopOwned.huff new file mode 100644 index 00000000..09840cc6 --- /dev/null +++ b/src/auth/__TEMP__zvezglymjookpccrxwupfpflpekwphopOwned.huff @@ -0,0 +1,106 @@ + +#define macro CONSTRUCTOR() = takes (0) returns (0) { + OWNED_CONSTRUCTOR() +} + +#define macro MAIN() = takes (0) returns (0) { + pc calldataload 0xe0 shr + OWNED_MAIN() + 0x00 dup1 revert +} + + +/// @title Owned +/// @notice SPDX-License-Identifier: MIT +/// @author asnared +/// @notice An single owner authorization module +/// @notice Adapted from + +// Interface +#define function setOwner(address) nonpayable returns () +#define function owner() view returns (address) + +// Events +#define event OwnerUpdated(address indexed user, address indexed newOwner) + +// Storage Slots +#define constant OWNER = FREE_STORAGE_POINTER() + +// CONSTRUCTOR +#define macro OWNED_CONSTRUCTOR() = takes (0) returns (0) { + // Copy the owner into memory + 0x20 // [size] - byte size to copy + 0x20 codesize sub // [offset, size] - offset in the code to copy from + 0x00 // [mem, offset, size] - offset in memory to copy to + codecopy // [] + + // Set the new owner + 0x00 mload // [owner] + dup1 // [owner, owner] + [OWNER] // [OWNER, owner, owner] + sstore // [owner] + + // Emit the owner updated event + caller // [from, owner] + __EVENT_HASH(OwnerUpdated) // [sig, from, owner] + 0x00 0x00 // [0, 0, sig, from, owner] + log3 // [] +} + +/// @notice Only Owner Modifier +#define macro IS_OWNER() = takes (0) returns (0) { + caller // [msg.sender] + [OWNER] sload // [owner, msg.sender] + eq authed jumpi // [authed] + + // Revert otherwise + 0x00 0x00 revert + + authed: +} + +/// @notice Set the Owner +/// @param {owner} [address] - The new owner +#define macro SET_OWNER() = takes (0) returns (0) { + // Check that the caller is authorized + IS_OWNER() + + // Set the new owner + 0x04 calldataload // [newOwner] + dup1 // [newOwner, newOwner] + [OWNER] sstore // [newOwner] + + // Emit the owner updated event + caller // [from, newOwner] + __EVENT_HASH(OwnerUpdated) // [sig, from, newOwner] + 0x00 0x00 // [0, 32, sig, from, newOwner] + log3 // [] + + stop +} + +/// @notice Get the owner of the contract +/// @return {owner} [address] - The owner of the contract +#define macro OWNER() = takes (0) returns (0) { + [OWNER] sload // [owner] + 0x00 mstore // [] + 0x20 0x00 return +} + +/// @notice Main Function Dispatcher +#define macro OWNED_MAIN() = takes (1) returns (1) { + // Input Stack: [function_selector] + + dup1 __FUNC_SIG(setOwner) eq set_owner jumpi + dup1 __FUNC_SIG(owner) eq owner jumpi + + // Bubble up to parent macro + no_match jump + + set_owner: + SET_OWNER() + owner: + OWNER() + + no_match: +} \ No newline at end of file diff --git a/src/data-structures/__TEMP__dbkprxxmslvmupkpkwuxxniuwscdqqrnArrays.huff b/src/data-structures/__TEMP__dbkprxxmslvmupkpkwuxxniuwscdqqrnArrays.huff new file mode 100644 index 00000000..d63bae3b --- /dev/null +++ b/src/data-structures/__TEMP__dbkprxxmslvmupkpkwuxxniuwscdqqrnArrays.huff @@ -0,0 +1,121 @@ +// Sets an array from calldata. +// sig: 0x226ce6b7 +#define function setArrayFromCalldata(uint256[]) view returns () + +// Returns an array. +// sig: 0xde9ee75c +#define function loadArray() view returns (uint256[] memory) + +#define constant LOCATION = FREE_STORAGE_POINTER() + +#define macro SET_FROM_CALLDATA() = takes(0) returns(0) { + [LOCATION] 0x04 + SET_ARRAY_FROM_CALLDATA() + stop +} + + +// Store the value for the given key. +#define macro RETURN() = takes(0) returns(0) { + [LOCATION] + RETURN_ARRAY(0x80) +} + +/* Main Macro - The contract entrypoint */ +#define macro MAIN() = takes(0) returns (0) { + // Identify which function is being called using the 4 byte function signature + 0x00 calldataload 0xE0 shr + dup1 __FUNC_SIG(setArrayFromCalldata) eq set_from_calldata jumpi + dup1 __FUNC_SIG(loadArray) eq load jumpi + + // Revert if otherwise + 0x00 0x00 revert + + set_from_calldata: + SET_FROM_CALLDATA() + load: + RETURN() +} + + +/// @title Arrays +/// @notice SPDX-License-Identifier: MIT +/// @author exp-table +/// @notice Array utility library for Solidity contracts + +/// @notice Sets an array in storage from calldata. +/// Note that since no assumptions is made regarding the context in which +/// this function is called, the position of the encoded array in the calldata +/// has to be specified. +#define macro SET_ARRAY_FROM_CALLDATA() = takes(2) returns (0) { + // Input stack: [calldata_start, slot] + // skip size of one individual element + 0x20 add // [calldata_start+0x20, slot] + dup1 0x20 add swap1 // [calldata_start+0x20, calldata_start+0x40, slot] + // load length + calldataload // [length, calldata_offset, slot] + // store length at slot + dup1 dup4 // [slot, length, length, calldata_offset, slot] + sstore // [length, calldata_offset, slot] + + // store slot in memory scratch space and compute hash + dup3 0x00 mstore // [length, calldata_offset, slot] + 0x20 0x00 sha3 // [sha3(slot), length, ,calldata_offset slot] + + // loop and store every element in slot sha3(slot)+n + 0x00 // [index(0), sha3(slot), length, calldata_offset, slot] + start jump + continue: + // if index == length -> it's over + eq end jumpi // [index(i), sha3(slot), length, calldata_offset, slot] + start: + // load from calldata + dup1 0x20 mul dup5 add calldataload // [array(i), index(i), sha3(slot), length, calldata_offset, slot] + // store at slot sha3(slot)+index + dup3 dup3 add sstore // [index(i), sha3(slot), length, calldata_offset, slot] + // inc index + 0x01 add // [index(i+1), sha3(slot), length, calldata_offset, slot] + dup3 dup2 // [index(i+1), length, index(i+1), sha3(slot), length, calldata_offset, slot] + continue jump + + end: +} + +/// @notice Returns an array in memory specified at {mem_ptr} +#define macro RETURN_ARRAY(mem_ptr) = takes(1) returns (0) { + // Input stack: [slot] + + // store the size of each element in memory + 0x20 mstore // [slot] + // [mem_ptr, slot] + // load length from storage + dup2 sload dup1 // [length, length, curr_mem_ptr, slot] + // store length in memory + swap2 0x20 add // [curr_mem_ptr+0x20, length, length, slot] + swap1 dup2 mstore // [curr_mem_ptr, length, slot] + + // store slot in memory scratch space and compute hash + swap2 0x00 mstore // [length, curr_mem_ptr] + 0x20 0x00 sha3 swap2 // [curr_mem_ptr, length, sha3(slot)] + + // loop and load every element in slot sha3(slot)+n + 0x00 start jump // [index(0), curr_mem_ptr, length, sha3(slot)] + continue: + // if index == length -> it's over + eq end jumpi // [index(i), curr_mem_ptr, length, sha3(slot)] + start: + // load from storage ; add index to sha3(slot) + dup1 dup5 add sload // [array(i), index(i), curr_mem_ptr, length, sha3(slot)] + // store in memory + swap1 swap2 0x20 add // [curr_mem_ptr+0x20, array(i), index(i), length, sha3(slot)] + dup1 swap2 swap1 mstore // [curr_mem_ptr+0x20, index(i), length, sha3(slot)] + // update index + swap1 0x01 add // [index(i+1), curr_mem_ptr, length, sha3(slot)] + dup1 dup4 + continue jump + + end: + // size of data to return = size of individual element + array length + encoded elements + swap2 0x02 add 0x05 shl // [size, curr_mem_ptr, index(i), sha3(slot)] + return +} \ No newline at end of file diff --git a/src/data-structures/__TEMP__fvwgxfmgyfyneyghrepikbyjmyskqxskHashmap.huff b/src/data-structures/__TEMP__fvwgxfmgyfyneyghrepikbyjmyskqxskHashmap.huff new file mode 100644 index 00000000..f603cb4c --- /dev/null +++ b/src/data-structures/__TEMP__fvwgxfmgyfyneyghrepikbyjmyskqxskHashmap.huff @@ -0,0 +1,317 @@ +// Returns the slot value for the given key. +// sig: 0x437b8ad6 +#define function loadElement(bytes32) view returns (bytes32) + +// Returns the slot value by hashing the given keys. +// sig: 0xf268de10 +#define function loadElementFromKeys(bytes32, bytes32) view returns (bytes32) + +// Returns the slot value by hashing the given slot and two keys. +// sig: 0xef5b4768 +#define function loadElementFromKeys2D(bytes32, bytes32, bytes32) view returns (bytes32) + +// Returns the slot value by hashing the given slot and three keys. +// sig: 0x0cc703f5 +#define function loadElementFromKeys3D(bytes32, bytes32, bytes32, bytes32) view returns (bytes32) + +// Stores the value for the given key. +// sig: 0x376caf9f +#define function storeElement(bytes32 key, bytes32 value) nonpayable returns () + +// Stores the value for the given keys +// sig: 0x2fdb44d8 +#define function storeElementFromKeys(bytes32 key1, bytes32 key2, bytes32 value) nonpayable returns () + +// Stores the value given a slot and two keys +// sig: 0x64fab984 +#define function storeElementFromKeys2D( + bytes32 slot, + bytes32 key1, + bytes32 key2, + bytes32 value +) nonpayable returns () + +// Stores the value given a slot and three keys +// sig: 0xd3b12314 +#define function storeElementFromKeys3D( + bytes32 slot, + bytes32 key1, + bytes32 key2, + bytes32 key3, + bytes32 value +) nonpayable returns () + +#define constant LOCATION = FREE_STORAGE_POINTER() + +// Get the value for the given key. +#define macro GET() = takes(0) returns(0) { + 0x04 calldataload + LOAD_ELEMENT(0x00) + 0x00 mstore + 0x20 0x00 return +} + +// Get the value for the given keys. +#define macro GET_FROM_KEYS() = takes(0) returns(0) { + 0x24 calldataload + 0x04 calldataload + LOAD_ELEMENT_FROM_KEYS(0x00) + 0x00 mstore + 0x20 0x00 return +} + +// Get the value for the given slot and two keys +#define macro GET_FROM_KEYS_2D() = takes(0) returns(0) { + 0x44 calldataload + 0x24 calldataload + 0x04 calldataload + LOAD_ELEMENT_FROM_KEYS_2D(0x00) + 0x00 mstore + 0x20 0x00 return +} + +// Get the value for the given slot and three keys +#define macro GET_FROM_KEYS_3D() = takes(0) returns(0) { + 0x64 calldataload + 0x44 calldataload + 0x24 calldataload + 0x04 calldataload + LOAD_ELEMENT_FROM_KEYS_3D(0x00) + 0x00 mstore + 0x20 0x00 return +} + +// Store the value for the given key. +#define macro STORE() = takes(0) returns(0) { + 0x24 calldataload + 0x04 calldataload + STORE_ELEMENT(0x00) + stop +} + +// Store the value for the given key. +#define macro STORE_FROM_KEYS() = takes(0) returns(0) { + 0x44 calldataload + 0x24 calldataload + 0x04 calldataload + STORE_ELEMENT_FROM_KEYS(0x00) + stop +} + +// Store the value for the given slot and two keys. +#define macro STORE_FROM_KEYS_2D() = takes(0) returns(0) { + 0x64 calldataload + 0x44 calldataload + 0x24 calldataload + 0x04 calldataload + STORE_ELEMENT_FROM_KEYS_2D(0x00) + stop +} + +// Store the value for the given slot and three keys. +#define macro STORE_FROM_KEYS_3D() = takes(0) returns(0) { + 0x84 calldataload + 0x64 calldataload + 0x44 calldataload + 0x24 calldataload + 0x04 calldataload + STORE_ELEMENT_FROM_KEYS_3D(0x00) + stop +} + +// Main Macro - The contract entrypoint +#define macro MAIN() = takes(0) returns (0) { + // Identify which function is being called using the 4 byte function signature + pc calldataload 0xE0 shr + + dup1 __FUNC_SIG(loadElement) eq load_element jumpi + dup1 __FUNC_SIG(loadElementFromKeys) eq load_element_from_keys jumpi + dup1 __FUNC_SIG(loadElementFromKeys2D) eq load_element_from_keys_2d jumpi + dup1 __FUNC_SIG(loadElementFromKeys3D) eq load_element_from_keys_3d jumpi + dup1 __FUNC_SIG(storeElement) eq store_element jumpi + dup1 __FUNC_SIG(storeElementFromKeys) eq store_element_from_keys jumpi + dup1 __FUNC_SIG(storeElementFromKeys2D) eq store_element_from_keys_2d jumpi + dup1 __FUNC_SIG(storeElementFromKeys3D) eq store_element_from_keys_3d jumpi + + // Revert if otherwise + 0x00 dup1 revert + + load_element: + GET() + load_element_from_keys: + GET_FROM_KEYS() + load_element_from_keys_2d: + GET_FROM_KEYS_2D() + load_element_from_keys_3d: + GET_FROM_KEYS_3D() + store_element: + STORE() + store_element_from_keys: + STORE_FROM_KEYS() + store_element_from_keys_2d: + STORE_FROM_KEYS_2D() + store_element_from_keys_3d: + STORE_FROM_KEYS_3D() +} + + +/// @title HashMap +/// @notice SPDX-License-Identifier: MIT +/// @author asnared +/// @notice A Module Encapsulating HashMap Methods +/// @notice Adapted from + +/// @notice Given a piece of data (ie an address), hash it, generating the storage slot for a hashmap. +#define macro GET_SLOT_FROM_KEY(mem_ptr) = takes(1) returns (1) { + // Input stack: [key] + // Load the data into memory and hash it, while preserving the memory location. + // [, key] + mstore // [] + + // Hash the data, generating a key. + 0x20 // [32] + // [, 32] + sha3 // [slot] +} + +/// @notice Given two keys (ie a slot and a key), hash them together, generating a slot for a secondary hashmap. +#define macro GET_SLOT_FROM_KEYS(mem_ptr) = takes(2) returns (1) { + // Input stack: [slot, key] + // Load the data into memory. + 0x20 add // [ + 32, slot, key] + mstore // [key] + // [, key] + mstore // [] + + // Hash the data, generating a slot. + 0x40 // [64] + // [, 64] + sha3 // [slot] +} + +/// @notice Calculate the slot from two keys +#define macro GET_SLOT_FROM_KEYS_2D(mem_ptr) = takes(3) returns (1) { + // Input stack: [slot, key1, key2] + // Load the data into memory + 0x20 add // [ + 32, slot, key1, key2] + mstore // [key1, key2] + + // next byte + // [, key1, key2] + mstore // [key2] + + 0x40 // [0x40, key2] + // [, 0x40, key2] + sha3 // [hash, key2] + + // concat the two keys + 0x20 add // [ + 32, hash, key2] put hash in memory + mstore // [key2] + + // next byte + // [, key2] + mstore // [] + + // Hash the data, generating a slot. + 0x40 // [0x40] + // [, 0x40] + sha3 // [slot] +} + +/// @notice Calculate the slot from three keys +#define macro GET_SLOT_FROM_KEYS_3D(mem_ptr) = takes(4) returns (1) { + // Input stack: [slot, key1, key2, key3] + // Load the data into memory + 0x20 add // [ + 32, slot, key1, key2, key3] + swap1 dup2 // [ + 32, slot, + 32, key1, key2, key3] + mstore // [ + 32, key1, key2, key3] + + swap1 // [, key1, + 32, key2, key3] + mstore // [ + 32, key2, key3] + + 0x40 // [0x40, + 32, key2, key3] + // [, 0x40, + 32, key2, key3] + sha3 // [slot1, + 32, key2, key3] + + // concat the first two keys + dup2 // [ + 32, slot1, + 32, key2, key3] put slot1 in memory + mstore // [ + 32, key2, key3] + + // put key2 in memory, before slot1 + swap1 // [key2, + 32, key3] + // [, key2, + 32, key3] + mstore // [key3] + + 0x40 // [0x40, + 32, key3] + // [, 0x40, + 32, key3] + sha3 // [slot2, + 32, key3] + + // concat with the third key + swap1 // [ + 32, slot2, key3] put slot2 in memory + mstore // [key3] + + // put key3 in memory, before slot2 + // [, key3] + mstore // [] + + // Hash the data, generating the final slot3 + 0x40 // [0x40] + // [, 0x40] + sha3 // [slot3] +} + +/// @notice Load an element onto the stack from a key +#define macro LOAD_ELEMENT(mem_ptr) = takes(1) returns(1) { + // Input stack: [key] + GET_SLOT_FROM_KEY() // [slot] + sload // [value] +} + +/// @notice Load an element onto the stack from two keys +#define macro LOAD_ELEMENT_FROM_KEYS(mem_ptr) = takes(2) returns(1) { + // Input stack: [key1, key2] + GET_SLOT_FROM_KEYS() // [slot] + sload // [value] +} + +/// @notice Load an element onto the stack from a slot and two keys +#define macro LOAD_ELEMENT_FROM_KEYS_2D(mem_ptr) = takes(3) returns(1) { + // Input stack: [slot, key1, key2] + GET_SLOT_FROM_KEYS_2D() // [slot] + sload // [value] +} + +/// @notice Load an element onto the stack from a slot and three keys +#define macro LOAD_ELEMENT_FROM_KEYS_3D(mem_ptr) = takes(4) returns(1) { + // Input stack: [slot, key1, key2, key3] + GET_SLOT_FROM_KEYS_3D() // [slot] + sload // [value] +} + +/// @notice Store an element from a key +#define macro STORE_ELEMENT(mem_ptr) = takes(2) returns(0) { + // Input stack: [key, value] + GET_SLOT_FROM_KEY() // [slot, value] + sstore // [] +} + +/// @notice Store an element from two keys +#define macro STORE_ELEMENT_FROM_KEYS(mem_ptr) = takes(3) returns (0) { + // Input stack: [key1, key2, value] + GET_SLOT_FROM_KEYS() // [slot, value] + sstore // [] +} + +/// @notice Store an element from a slot and two keys +#define macro STORE_ELEMENT_FROM_KEYS_2D(mem_ptr) = takes(4) returns (0) { + // Input stack: [slot, key1, key2, value] + GET_SLOT_FROM_KEYS_2D() // [slot, value] + sstore // [] +} + +/// @notice Store an element from a slot and three keys +#define macro STORE_ELEMENT_FROM_KEYS_3D(mem_ptr) = takes(5) returns (0) { + // Input stack: [slot, key1, key2, key3, value] + GET_SLOT_FROM_KEYS_3D() // [slot, value] + sstore // [] +} \ No newline at end of file diff --git a/src/data-structures/__TEMP__jqxhhzaaidyagiaawzeyxpvkgxcxwtgqHashmap.huff b/src/data-structures/__TEMP__jqxhhzaaidyagiaawzeyxpvkgxcxwtgqHashmap.huff new file mode 100644 index 00000000..f603cb4c --- /dev/null +++ b/src/data-structures/__TEMP__jqxhhzaaidyagiaawzeyxpvkgxcxwtgqHashmap.huff @@ -0,0 +1,317 @@ +// Returns the slot value for the given key. +// sig: 0x437b8ad6 +#define function loadElement(bytes32) view returns (bytes32) + +// Returns the slot value by hashing the given keys. +// sig: 0xf268de10 +#define function loadElementFromKeys(bytes32, bytes32) view returns (bytes32) + +// Returns the slot value by hashing the given slot and two keys. +// sig: 0xef5b4768 +#define function loadElementFromKeys2D(bytes32, bytes32, bytes32) view returns (bytes32) + +// Returns the slot value by hashing the given slot and three keys. +// sig: 0x0cc703f5 +#define function loadElementFromKeys3D(bytes32, bytes32, bytes32, bytes32) view returns (bytes32) + +// Stores the value for the given key. +// sig: 0x376caf9f +#define function storeElement(bytes32 key, bytes32 value) nonpayable returns () + +// Stores the value for the given keys +// sig: 0x2fdb44d8 +#define function storeElementFromKeys(bytes32 key1, bytes32 key2, bytes32 value) nonpayable returns () + +// Stores the value given a slot and two keys +// sig: 0x64fab984 +#define function storeElementFromKeys2D( + bytes32 slot, + bytes32 key1, + bytes32 key2, + bytes32 value +) nonpayable returns () + +// Stores the value given a slot and three keys +// sig: 0xd3b12314 +#define function storeElementFromKeys3D( + bytes32 slot, + bytes32 key1, + bytes32 key2, + bytes32 key3, + bytes32 value +) nonpayable returns () + +#define constant LOCATION = FREE_STORAGE_POINTER() + +// Get the value for the given key. +#define macro GET() = takes(0) returns(0) { + 0x04 calldataload + LOAD_ELEMENT(0x00) + 0x00 mstore + 0x20 0x00 return +} + +// Get the value for the given keys. +#define macro GET_FROM_KEYS() = takes(0) returns(0) { + 0x24 calldataload + 0x04 calldataload + LOAD_ELEMENT_FROM_KEYS(0x00) + 0x00 mstore + 0x20 0x00 return +} + +// Get the value for the given slot and two keys +#define macro GET_FROM_KEYS_2D() = takes(0) returns(0) { + 0x44 calldataload + 0x24 calldataload + 0x04 calldataload + LOAD_ELEMENT_FROM_KEYS_2D(0x00) + 0x00 mstore + 0x20 0x00 return +} + +// Get the value for the given slot and three keys +#define macro GET_FROM_KEYS_3D() = takes(0) returns(0) { + 0x64 calldataload + 0x44 calldataload + 0x24 calldataload + 0x04 calldataload + LOAD_ELEMENT_FROM_KEYS_3D(0x00) + 0x00 mstore + 0x20 0x00 return +} + +// Store the value for the given key. +#define macro STORE() = takes(0) returns(0) { + 0x24 calldataload + 0x04 calldataload + STORE_ELEMENT(0x00) + stop +} + +// Store the value for the given key. +#define macro STORE_FROM_KEYS() = takes(0) returns(0) { + 0x44 calldataload + 0x24 calldataload + 0x04 calldataload + STORE_ELEMENT_FROM_KEYS(0x00) + stop +} + +// Store the value for the given slot and two keys. +#define macro STORE_FROM_KEYS_2D() = takes(0) returns(0) { + 0x64 calldataload + 0x44 calldataload + 0x24 calldataload + 0x04 calldataload + STORE_ELEMENT_FROM_KEYS_2D(0x00) + stop +} + +// Store the value for the given slot and three keys. +#define macro STORE_FROM_KEYS_3D() = takes(0) returns(0) { + 0x84 calldataload + 0x64 calldataload + 0x44 calldataload + 0x24 calldataload + 0x04 calldataload + STORE_ELEMENT_FROM_KEYS_3D(0x00) + stop +} + +// Main Macro - The contract entrypoint +#define macro MAIN() = takes(0) returns (0) { + // Identify which function is being called using the 4 byte function signature + pc calldataload 0xE0 shr + + dup1 __FUNC_SIG(loadElement) eq load_element jumpi + dup1 __FUNC_SIG(loadElementFromKeys) eq load_element_from_keys jumpi + dup1 __FUNC_SIG(loadElementFromKeys2D) eq load_element_from_keys_2d jumpi + dup1 __FUNC_SIG(loadElementFromKeys3D) eq load_element_from_keys_3d jumpi + dup1 __FUNC_SIG(storeElement) eq store_element jumpi + dup1 __FUNC_SIG(storeElementFromKeys) eq store_element_from_keys jumpi + dup1 __FUNC_SIG(storeElementFromKeys2D) eq store_element_from_keys_2d jumpi + dup1 __FUNC_SIG(storeElementFromKeys3D) eq store_element_from_keys_3d jumpi + + // Revert if otherwise + 0x00 dup1 revert + + load_element: + GET() + load_element_from_keys: + GET_FROM_KEYS() + load_element_from_keys_2d: + GET_FROM_KEYS_2D() + load_element_from_keys_3d: + GET_FROM_KEYS_3D() + store_element: + STORE() + store_element_from_keys: + STORE_FROM_KEYS() + store_element_from_keys_2d: + STORE_FROM_KEYS_2D() + store_element_from_keys_3d: + STORE_FROM_KEYS_3D() +} + + +/// @title HashMap +/// @notice SPDX-License-Identifier: MIT +/// @author asnared +/// @notice A Module Encapsulating HashMap Methods +/// @notice Adapted from + +/// @notice Given a piece of data (ie an address), hash it, generating the storage slot for a hashmap. +#define macro GET_SLOT_FROM_KEY(mem_ptr) = takes(1) returns (1) { + // Input stack: [key] + // Load the data into memory and hash it, while preserving the memory location. + // [, key] + mstore // [] + + // Hash the data, generating a key. + 0x20 // [32] + // [, 32] + sha3 // [slot] +} + +/// @notice Given two keys (ie a slot and a key), hash them together, generating a slot for a secondary hashmap. +#define macro GET_SLOT_FROM_KEYS(mem_ptr) = takes(2) returns (1) { + // Input stack: [slot, key] + // Load the data into memory. + 0x20 add // [ + 32, slot, key] + mstore // [key] + // [, key] + mstore // [] + + // Hash the data, generating a slot. + 0x40 // [64] + // [, 64] + sha3 // [slot] +} + +/// @notice Calculate the slot from two keys +#define macro GET_SLOT_FROM_KEYS_2D(mem_ptr) = takes(3) returns (1) { + // Input stack: [slot, key1, key2] + // Load the data into memory + 0x20 add // [ + 32, slot, key1, key2] + mstore // [key1, key2] + + // next byte + // [, key1, key2] + mstore // [key2] + + 0x40 // [0x40, key2] + // [, 0x40, key2] + sha3 // [hash, key2] + + // concat the two keys + 0x20 add // [ + 32, hash, key2] put hash in memory + mstore // [key2] + + // next byte + // [, key2] + mstore // [] + + // Hash the data, generating a slot. + 0x40 // [0x40] + // [, 0x40] + sha3 // [slot] +} + +/// @notice Calculate the slot from three keys +#define macro GET_SLOT_FROM_KEYS_3D(mem_ptr) = takes(4) returns (1) { + // Input stack: [slot, key1, key2, key3] + // Load the data into memory + 0x20 add // [ + 32, slot, key1, key2, key3] + swap1 dup2 // [ + 32, slot, + 32, key1, key2, key3] + mstore // [ + 32, key1, key2, key3] + + swap1 // [, key1, + 32, key2, key3] + mstore // [ + 32, key2, key3] + + 0x40 // [0x40, + 32, key2, key3] + // [, 0x40, + 32, key2, key3] + sha3 // [slot1, + 32, key2, key3] + + // concat the first two keys + dup2 // [ + 32, slot1, + 32, key2, key3] put slot1 in memory + mstore // [ + 32, key2, key3] + + // put key2 in memory, before slot1 + swap1 // [key2, + 32, key3] + // [, key2, + 32, key3] + mstore // [key3] + + 0x40 // [0x40, + 32, key3] + // [, 0x40, + 32, key3] + sha3 // [slot2, + 32, key3] + + // concat with the third key + swap1 // [ + 32, slot2, key3] put slot2 in memory + mstore // [key3] + + // put key3 in memory, before slot2 + // [, key3] + mstore // [] + + // Hash the data, generating the final slot3 + 0x40 // [0x40] + // [, 0x40] + sha3 // [slot3] +} + +/// @notice Load an element onto the stack from a key +#define macro LOAD_ELEMENT(mem_ptr) = takes(1) returns(1) { + // Input stack: [key] + GET_SLOT_FROM_KEY() // [slot] + sload // [value] +} + +/// @notice Load an element onto the stack from two keys +#define macro LOAD_ELEMENT_FROM_KEYS(mem_ptr) = takes(2) returns(1) { + // Input stack: [key1, key2] + GET_SLOT_FROM_KEYS() // [slot] + sload // [value] +} + +/// @notice Load an element onto the stack from a slot and two keys +#define macro LOAD_ELEMENT_FROM_KEYS_2D(mem_ptr) = takes(3) returns(1) { + // Input stack: [slot, key1, key2] + GET_SLOT_FROM_KEYS_2D() // [slot] + sload // [value] +} + +/// @notice Load an element onto the stack from a slot and three keys +#define macro LOAD_ELEMENT_FROM_KEYS_3D(mem_ptr) = takes(4) returns(1) { + // Input stack: [slot, key1, key2, key3] + GET_SLOT_FROM_KEYS_3D() // [slot] + sload // [value] +} + +/// @notice Store an element from a key +#define macro STORE_ELEMENT(mem_ptr) = takes(2) returns(0) { + // Input stack: [key, value] + GET_SLOT_FROM_KEY() // [slot, value] + sstore // [] +} + +/// @notice Store an element from two keys +#define macro STORE_ELEMENT_FROM_KEYS(mem_ptr) = takes(3) returns (0) { + // Input stack: [key1, key2, value] + GET_SLOT_FROM_KEYS() // [slot, value] + sstore // [] +} + +/// @notice Store an element from a slot and two keys +#define macro STORE_ELEMENT_FROM_KEYS_2D(mem_ptr) = takes(4) returns (0) { + // Input stack: [slot, key1, key2, value] + GET_SLOT_FROM_KEYS_2D() // [slot, value] + sstore // [] +} + +/// @notice Store an element from a slot and three keys +#define macro STORE_ELEMENT_FROM_KEYS_3D(mem_ptr) = takes(5) returns (0) { + // Input stack: [slot, key1, key2, key3, value] + GET_SLOT_FROM_KEYS_3D() // [slot, value] + sstore // [] +} \ No newline at end of file diff --git a/src/data-structures/__TEMP__lwkvhrrmofongwpxrjtworcwgnfqpxluBytes.huff b/src/data-structures/__TEMP__lwkvhrrmofongwpxrjtworcwgnfqpxluBytes.huff new file mode 100644 index 00000000..fa739be2 --- /dev/null +++ b/src/data-structures/__TEMP__lwkvhrrmofongwpxrjtworcwgnfqpxluBytes.huff @@ -0,0 +1,349 @@ +#define macro SET_STOR(offset, value) = takes(2) returns(0) { + sstore // [] +} + +#define macro CONCAT_MEMORY_AND_SET1() = takes (0) returns (0) { + // remove func selector + pop + + 0x20 0x00 mstore + 0xbabe1babe1babe1babe1babe1babe1babe1babe1babe1babe1babe1babe1babe 0x20 mstore + + 0x20 0x40 mstore + 0xbabe2babe2babe2babe2babe2babe2babe2babe2babe2babe2babe2babe2babe 0x60 mstore + + 0x40 0x00 // [mem_ptr1, mem_ptr2] + CONCAT_MEMORY() // [pos] + + dup1 mload // [len, pos] + 0x00 SET_STOR() // [pos] + + dup1 0x20 add mload // [babe1, pos] + 0x20 SET_STOR() // [pos] + + 0x40 add mload // [babe2, pos] + 0x40 SET_STOR() // [pos] + + stop +} + +#define macro CONCAT_MEMORY_AND_SET2() = takes (0) returns (0) { + pop + + 0x20 0x00 mstore + 0xbabe1babe1babe1babe1babe1babe1babe1babe1babe1babe1babe1babe1babe 0x20 mstore + + 0x40 0x40 mstore + 0xbabe2babe2babe2babe2babe2babe2babe2babe2babe2babe2babe2babe2babe 0x60 mstore + 0xbabe2babe2babe2babe2babe2babe2babe2babe2babe2babe2babe2babe2babe 0x80 mstore + + 0x40 0x00 + CONCAT_MEMORY() + + dup1 mload + 0x00 SET_STOR() + + dup1 0x20 add mload + 0x20 SET_STOR() + + dup1 0x40 add mload + 0x40 SET_STOR() + + 0x60 add mload + 0x60 SET_STOR() + + stop +} + +#define macro CONCAT_MEMORY_AND_SET3() = takes (0) returns (0) { + pop + + 0x20 0x00 mstore + 0xbabe1babe1babe1babe1babe1babe1babe1babe1babe1babe1babe1babe1babe 0x20 mstore + + 0x00 0x40 mstore + + 0x40 0x00 + CONCAT_MEMORY() + + dup1 mload + 0x00 SET_STOR() + + dup1 0x20 add mload + 0x20 SET_STOR() + + stop +} + +#define macro CONCAT_MEMORY_AND_SET4() = takes (0) returns (0) { + pop + + 0x20 0x00 mstore + 0xbabe1babe1babe1babe1babe1babe1babe1babe1babe1babe1babe1babe1babe 0x20 mstore + + 0x05 0x40 mstore + __RIGHTPAD(0xbabe2babe2) 0x60 mstore + + 0x40 0x00 + CONCAT_MEMORY() + + dup1 mload + 0x00 SET_STOR() + + dup1 0x20 add mload + 0x20 SET_STOR() + + dup1 0x40 add mload + 0x40 SET_STOR() + + stop +} + +#define macro CONCAT_MEMORY_AND_SET5() = takes (0) returns (0) { + pop + + 0x0a 0x00 mstore + __RIGHTPAD(0xbabe1babe1babe1babe1) 0x20 mstore + + 0x05 0x40 mstore + __RIGHTPAD(0xbabe2babe2) 0x60 mstore + + 0x40 0x00 + CONCAT_MEMORY() + + dup1 mload + 0x00 SET_STOR() + + dup1 0x20 add mload + 0x20 SET_STOR() + + stop +} + +#define macro CONCAT_MEMORY_AND_SET6() = takes (0) returns (0) { + pop + + // don't need to be % 0x20 + 0x0a 0x05 mstore + __RIGHTPAD(0xbabe1babe1babe1babe1) 0x25 mstore + + 0x05 0x48 mstore + __RIGHTPAD(0xbabe2babe2) 0x68 mstore + + 0x48 0x05 + CONCAT_MEMORY() // [pos] + + dup1 mload // [len, pos] + 0x00 SET_STOR() // [pos] + + dup1 0x20 add mload // [babe1, pos] + 0x20 SET_STOR() // [pos] + + stop +} + +#define macro SLICE_MEMORY_AND_SET1() = takes (0) returns (0) { + pop + + 0x20 0x00 mstore + 0xbabe1babe1babe1babe1babe1babe1babe1babe1babe1babe1babe1babe1babe 0x20 mstore + + 0x10 0x00 0x00 // [mem_ptr, start, length] + SLICE_MEMORY() // [slice_ptr] + + dup1 mload + 0x00 SET_STOR() + + dup1 0x20 add mload + 0x20 SET_STOR() + + stop +} + +#define macro SLICE_MEMORY_AND_SET2() = takes (0) returns (0) { + pop + + 0x40 0x00 mstore + 0xbabe1babe1babe1babe1babe1babe1babe1babe1babe1babe1babe1babe1babe 0x20 mstore + 0xbabe2babe2babe2babe2babe2babe2babe2babe2babe2babe2babe2babe2babe 0x40 mstore + + 0x24 0x02 0x00 + SLICE_MEMORY() + + dup1 mload + 0x00 SET_STOR() + + dup1 0x20 add mload + 0x20 SET_STOR() + + dup1 0x40 add mload + 0x40 SET_STOR() + + stop +} + +#define macro SLICE_MEMORY_AND_SET3() = takes (0) returns (0) { + pop + + 0x40 0x07 mstore + 0xbabe1babe1babe1babe1babe1babe1babe1babe1babe1babe1babe1babe1babe 0x27 mstore + __RIGHTPAD(0xbabe2bab) 0x47 mstore + + 0x04 0x20 0x07 + SLICE_MEMORY() + + dup1 mload + 0x00 SET_STOR() + + dup1 0x20 add mload + 0x20 SET_STOR() + + stop +} + +#define macro MAIN() = takes (0) returns (0) { + 0x00 calldataload 0xE0 shr + dup1 __FUNC_SIG("concatMemoryAndSet1()") eq concatMemoryAndSet1 jumpi + dup1 __FUNC_SIG("concatMemoryAndSet2()") eq concatMemoryAndSet2 jumpi + dup1 __FUNC_SIG("concatMemoryAndSet3()") eq concatMemoryAndSet3 jumpi + dup1 __FUNC_SIG("concatMemoryAndSet4()") eq concatMemoryAndSet4 jumpi + dup1 __FUNC_SIG("concatMemoryAndSet5()") eq concatMemoryAndSet5 jumpi + dup1 __FUNC_SIG("concatMemoryAndSet6()") eq concatMemoryAndSet6 jumpi + dup1 __FUNC_SIG("sliceMemoryAndSet1()") eq sliceMemoryAndSet1 jumpi + dup1 __FUNC_SIG("sliceMemoryAndSet2()") eq sliceMemoryAndSet2 jumpi + dup1 __FUNC_SIG("sliceMemoryAndSet3()") eq sliceMemoryAndSet3 jumpi + + 0x00 0x00 revert + + concatMemoryAndSet1: + CONCAT_MEMORY_AND_SET1() + concatMemoryAndSet2: + CONCAT_MEMORY_AND_SET2() + concatMemoryAndSet3: + CONCAT_MEMORY_AND_SET3() + concatMemoryAndSet4: + CONCAT_MEMORY_AND_SET4() + concatMemoryAndSet5: + CONCAT_MEMORY_AND_SET5() + concatMemoryAndSet6: + CONCAT_MEMORY_AND_SET6() + sliceMemoryAndSet1: + SLICE_MEMORY_AND_SET1() + sliceMemoryAndSet2: + SLICE_MEMORY_AND_SET2() + sliceMemoryAndSet3: + SLICE_MEMORY_AND_SET3() +} + + +/// @title Bytes +/// @notice SPDX-License-Identifier: MIT +/// @author Franfran +/// @notice Low-level operations on bytes +/// @notice Adapted from BytesLib (https://github.com/GNSPS/solidity-bytes-utils/blob/master/contracts/BytesLib.sol) + +/// @notice Concatenate two bytes arrays +/// @notice Takes in two pointers of the bytes to concatenate that must be sorted +/// @return Pointer of the new appended concatenated bytes array in the memory +/// @dev Warning! This assumes that the pointer in the memory of the second bytes chunk is after mem_ptr1 + 0x20 +#define macro CONCAT_MEMORY() = takes(2) returns(1) { + // input stack // [mem_ptr1, mem_ptr2] + + // setup stack and memory for the next iterations + dup2 mload swap1 // [mem_ptr1, len2, mem_ptr2] + msize swap1 // [mem_ptr1, free_loc_pos, len2, mem_ptr2] + dup1 mload dup4 // [len2, len1, mem_ptr1, free_loc_pos, len2, mem_ptr2] + dup2 add msize mstore // [len1, mem_ptr1, free_loc_pos, len2, mem_ptr2] + + swap1 0x20 add // [index(i), len1, free_loc_pos, len2, mem_ptr2] + msize // [index(j), index(i), len1, free_loc_pos, len2, mem_ptr2] + swap2 0x00 // [is_sec_loop, len1, index(i), index(j), free_loc_pos, len2, mem_ptr2] + + // i is the index where we get (mload) the array element and j is the index where we store (mstore) the array at j + loop: // [is_sec_loop, len_left, index(i), index(j), free_loc_pos, len2, mem_ptr2] + dup2 iszero empty_slot jumpi // [is_sec_loop, len_left, index(i), index(j), free_loc_pos, len2, mem_ptr2] + + dup3 mload // [word, is_sec_loop, len_left, index(i), index(j), free_loc_pos, len2, mem_ptr2] + dup3 0x20 gt iszero // [is_full_slot, word, is_sec_loop, len_left, index(i), index(j), free_loc_pos, len2, mem_ptr2] + full_slot jumpi // [word, is_sec_loop, len_left, index(i), index(j), free_loc_pos, len2, mem_ptr2] + + // else it's not a full slot, we're hitting an end. Then clean memory slot and update j with a partial length + dup3 0x20 sub // [pad_len, word, is_sec_loop, len_left, index(i), index(j), free_loc_pos, len2, mem_ptr2] + 0x08 mul swap1 dup2 // [shift, word, shift, is_sec_loop, len_left, index(i), index(j), free_loc_pos, len2, mem_ptr2] + shr // [left_padded_word, shift, is_sec_loop, len_left, index(i), index(j), free_loc_pos, len2, mem_ptr2] + swap1 shl // [clean_word, is_sec_loop, len_left, index(i), index(j), free_loc_pos, len2, mem_ptr2] + dup5 mstore // [is_sec_loop, len_left, index(i), index(j), free_loc_pos, len2, mem_ptr2] + swap3 add swap2 // [is_sec_loop, index(i), index(j + 1), free_loc_pos, len2, mem_ptr2] + + // here we check if current loop is for the 2nd array + swap1 pop // [is_sec_loop, index(j + 1), free_loc_pos, len2, mem_ptr2] + iszero bridge jumpi // [index(j + 1), free_loc_pos, len2, mem_ptr2] + pop break jump // [free_loc_pos, len2, mem_ptr2] + + empty_slot: // [is_sec_loop, len_left, index(i), index(j), free_loc_pos, len2, mem_ptr2] + swap2 pop pop // [is_sec_loop, index(j), free_loc_pos, len2, mem_ptr2] + iszero bridge jumpi // [index(j), free_loc_pos, len2, mem_ptr2] + pop break jump // [free_loc_pos, len2, mem_ptr2] + + bridge: // [index(j), free_loc_pos, len2, mem_ptr2] + dup4 0x20 add // [index(i), index(j), free_loc_pos, len2, mem_ptr2] + dup5 // [len2, index(i), index(j), free_loc_pos, len2, mem_ptr2] + 0x01 // [is_sec_loop, len2, index(i), index(j), free_loc_pos, len2, mem_ptr2] + loop jump + + full_slot: // [word, is_sec_loop, len_left, index(i), index(j), free_loc_pos, len2, mem_ptr2] + dup5 mstore // [is_sec_loop, len_left, index(i), index(j), free_loc_pos, len2, mem_ptr2] + swap1 0x20 swap1 sub // [len_left - 0x20, is_sec_loop, index(i), index(j), free_loc_pos, len2, mem_ptr2] + swap2 0x20 add // [index(i + 1), is_sec_loop, len_left - 0x20, index(j), free_loc_pos, len2, mem_ptr2] + swap3 0x20 add // [index(j + 1), is_sec_loop, len_left - 0x20, index(i + 1), free_loc_pos, len2, mem_ptr2] + swap3 swap2 swap1 // [is_sec_loop, len_left - 0x20, index(i + 1), index(j + 1), free_loc_pos, len2, mem_ptr2] + loop jump + + break: // [free_loc_pos, len2, mem_ptr2] + swap2 pop pop // [free_loc_pos] +} + +/// @param Pointer in memory of the start of the bytes array +/// @param Start position of the slice relative to the array +/// @param Length of the output slice +/// @return Pointer of the new appended concatenated bytes array in the memory +/// @dev Warning! This assumes that the length of the output slice is less or equal the length of the bytes array (bytes.len < slice.len) +/// @dev Warning! This assumes that the start of the bytes array is not out of bounds (start < len + mem_ptr) +#define macro SLICE_MEMORY() = takes(3) returns(1) { + // input stack // [mem_ptr, start, length] + + msize dup4 msize mstore // [free_loc_pos, mem_ptr, start, length] + msize swap4 // [length, free_loc_pos, mem_ptr, start, index(j)] + // index(i) = mem_ptr + start + 0x20 + swap1 swap3 // [start, length, mem_ptr, free_loc_pos, index(j)] + swap1 swap2 // [mem_ptr, start, length, free_loc_pos, index(j)] + 0x20 add add // [index(i), length, free_loc_pos, index(j)] + + // we load our slice chunk at i and store it in a free memory location at j + loop: // [index(i), length_left, free_loc_pos, index(j)] + dup1 mload // [slice_chunk, index(i), length_left, free_loc_pos, index(j)] + + // if current is not full slot, then load the last bytes and break + 0x20 dup4 lt // [is_not_full_slot, slice_chunk, index(i), length_left, free_loc_pos, index(j)] + break jumpi // [slice_chunk, index(i), length_left, free_loc_pos, index(j)] + + dup5 mstore // [index(i), length_left, free_loc_pos, index(j)] + + 0x20 add swap3 // [free_loc, length_left, free_loc_pos, index(i+1)] + 0x20 add swap3 // [index(i+1), length_left, free_loc_pos, free_loc + 1] + swap1 0x20 // [0x20, length_left, index(i+1), free_loc_pos, free_loc + 1] + swap1 sub // [length_left - 1, index(i+1), free_loc_pos, free_loc + 1] + swap1 // [index(i+1), length_left - 1, free_loc_pos, free_loc + 1] + + loop jump + + break: // [slice_chunk, index(i), length, free_loc_pos, index(j)] + // store the remaining length + dup3 0x20 sub // [zero_length, slice_chunk, index(i), length, free_loc_pos, index(j)] + 0x08 mul swap1 dup2 // [shift, slice_chunk, shift, index(i), length, free_loc_pos, index(j)] + shr // [left_pad_slice, shift, index(i), length, free_loc_pos, index(j)] + swap1 shl // [slice_chunk, index(i), length, free_loc_pos, index(j)] + dup5 mstore // [index(i), length, free_loc_pos, index(j)] + + pop pop swap1 pop // [free_loc_pos] +} diff --git a/src/data-structures/__TEMP__swmivzahxlhrjuiphjztstbcaymhckevArrays.huff b/src/data-structures/__TEMP__swmivzahxlhrjuiphjztstbcaymhckevArrays.huff new file mode 100644 index 00000000..d63bae3b --- /dev/null +++ b/src/data-structures/__TEMP__swmivzahxlhrjuiphjztstbcaymhckevArrays.huff @@ -0,0 +1,121 @@ +// Sets an array from calldata. +// sig: 0x226ce6b7 +#define function setArrayFromCalldata(uint256[]) view returns () + +// Returns an array. +// sig: 0xde9ee75c +#define function loadArray() view returns (uint256[] memory) + +#define constant LOCATION = FREE_STORAGE_POINTER() + +#define macro SET_FROM_CALLDATA() = takes(0) returns(0) { + [LOCATION] 0x04 + SET_ARRAY_FROM_CALLDATA() + stop +} + + +// Store the value for the given key. +#define macro RETURN() = takes(0) returns(0) { + [LOCATION] + RETURN_ARRAY(0x80) +} + +/* Main Macro - The contract entrypoint */ +#define macro MAIN() = takes(0) returns (0) { + // Identify which function is being called using the 4 byte function signature + 0x00 calldataload 0xE0 shr + dup1 __FUNC_SIG(setArrayFromCalldata) eq set_from_calldata jumpi + dup1 __FUNC_SIG(loadArray) eq load jumpi + + // Revert if otherwise + 0x00 0x00 revert + + set_from_calldata: + SET_FROM_CALLDATA() + load: + RETURN() +} + + +/// @title Arrays +/// @notice SPDX-License-Identifier: MIT +/// @author exp-table +/// @notice Array utility library for Solidity contracts + +/// @notice Sets an array in storage from calldata. +/// Note that since no assumptions is made regarding the context in which +/// this function is called, the position of the encoded array in the calldata +/// has to be specified. +#define macro SET_ARRAY_FROM_CALLDATA() = takes(2) returns (0) { + // Input stack: [calldata_start, slot] + // skip size of one individual element + 0x20 add // [calldata_start+0x20, slot] + dup1 0x20 add swap1 // [calldata_start+0x20, calldata_start+0x40, slot] + // load length + calldataload // [length, calldata_offset, slot] + // store length at slot + dup1 dup4 // [slot, length, length, calldata_offset, slot] + sstore // [length, calldata_offset, slot] + + // store slot in memory scratch space and compute hash + dup3 0x00 mstore // [length, calldata_offset, slot] + 0x20 0x00 sha3 // [sha3(slot), length, ,calldata_offset slot] + + // loop and store every element in slot sha3(slot)+n + 0x00 // [index(0), sha3(slot), length, calldata_offset, slot] + start jump + continue: + // if index == length -> it's over + eq end jumpi // [index(i), sha3(slot), length, calldata_offset, slot] + start: + // load from calldata + dup1 0x20 mul dup5 add calldataload // [array(i), index(i), sha3(slot), length, calldata_offset, slot] + // store at slot sha3(slot)+index + dup3 dup3 add sstore // [index(i), sha3(slot), length, calldata_offset, slot] + // inc index + 0x01 add // [index(i+1), sha3(slot), length, calldata_offset, slot] + dup3 dup2 // [index(i+1), length, index(i+1), sha3(slot), length, calldata_offset, slot] + continue jump + + end: +} + +/// @notice Returns an array in memory specified at {mem_ptr} +#define macro RETURN_ARRAY(mem_ptr) = takes(1) returns (0) { + // Input stack: [slot] + + // store the size of each element in memory + 0x20 mstore // [slot] + // [mem_ptr, slot] + // load length from storage + dup2 sload dup1 // [length, length, curr_mem_ptr, slot] + // store length in memory + swap2 0x20 add // [curr_mem_ptr+0x20, length, length, slot] + swap1 dup2 mstore // [curr_mem_ptr, length, slot] + + // store slot in memory scratch space and compute hash + swap2 0x00 mstore // [length, curr_mem_ptr] + 0x20 0x00 sha3 swap2 // [curr_mem_ptr, length, sha3(slot)] + + // loop and load every element in slot sha3(slot)+n + 0x00 start jump // [index(0), curr_mem_ptr, length, sha3(slot)] + continue: + // if index == length -> it's over + eq end jumpi // [index(i), curr_mem_ptr, length, sha3(slot)] + start: + // load from storage ; add index to sha3(slot) + dup1 dup5 add sload // [array(i), index(i), curr_mem_ptr, length, sha3(slot)] + // store in memory + swap1 swap2 0x20 add // [curr_mem_ptr+0x20, array(i), index(i), length, sha3(slot)] + dup1 swap2 swap1 mstore // [curr_mem_ptr+0x20, index(i), length, sha3(slot)] + // update index + swap1 0x01 add // [index(i+1), curr_mem_ptr, length, sha3(slot)] + dup1 dup4 + continue jump + + end: + // size of data to return = size of individual element + array length + encoded elements + swap2 0x02 add 0x05 shl // [size, curr_mem_ptr, index(i), sha3(slot)] + return +} \ No newline at end of file diff --git a/src/data-structures/__TEMP__wvnaxkgsgqemkcqoqqvognrxtldwtppxBytes.huff b/src/data-structures/__TEMP__wvnaxkgsgqemkcqoqqvognrxtldwtppxBytes.huff new file mode 100644 index 00000000..fa739be2 --- /dev/null +++ b/src/data-structures/__TEMP__wvnaxkgsgqemkcqoqqvognrxtldwtppxBytes.huff @@ -0,0 +1,349 @@ +#define macro SET_STOR(offset, value) = takes(2) returns(0) { + sstore // [] +} + +#define macro CONCAT_MEMORY_AND_SET1() = takes (0) returns (0) { + // remove func selector + pop + + 0x20 0x00 mstore + 0xbabe1babe1babe1babe1babe1babe1babe1babe1babe1babe1babe1babe1babe 0x20 mstore + + 0x20 0x40 mstore + 0xbabe2babe2babe2babe2babe2babe2babe2babe2babe2babe2babe2babe2babe 0x60 mstore + + 0x40 0x00 // [mem_ptr1, mem_ptr2] + CONCAT_MEMORY() // [pos] + + dup1 mload // [len, pos] + 0x00 SET_STOR() // [pos] + + dup1 0x20 add mload // [babe1, pos] + 0x20 SET_STOR() // [pos] + + 0x40 add mload // [babe2, pos] + 0x40 SET_STOR() // [pos] + + stop +} + +#define macro CONCAT_MEMORY_AND_SET2() = takes (0) returns (0) { + pop + + 0x20 0x00 mstore + 0xbabe1babe1babe1babe1babe1babe1babe1babe1babe1babe1babe1babe1babe 0x20 mstore + + 0x40 0x40 mstore + 0xbabe2babe2babe2babe2babe2babe2babe2babe2babe2babe2babe2babe2babe 0x60 mstore + 0xbabe2babe2babe2babe2babe2babe2babe2babe2babe2babe2babe2babe2babe 0x80 mstore + + 0x40 0x00 + CONCAT_MEMORY() + + dup1 mload + 0x00 SET_STOR() + + dup1 0x20 add mload + 0x20 SET_STOR() + + dup1 0x40 add mload + 0x40 SET_STOR() + + 0x60 add mload + 0x60 SET_STOR() + + stop +} + +#define macro CONCAT_MEMORY_AND_SET3() = takes (0) returns (0) { + pop + + 0x20 0x00 mstore + 0xbabe1babe1babe1babe1babe1babe1babe1babe1babe1babe1babe1babe1babe 0x20 mstore + + 0x00 0x40 mstore + + 0x40 0x00 + CONCAT_MEMORY() + + dup1 mload + 0x00 SET_STOR() + + dup1 0x20 add mload + 0x20 SET_STOR() + + stop +} + +#define macro CONCAT_MEMORY_AND_SET4() = takes (0) returns (0) { + pop + + 0x20 0x00 mstore + 0xbabe1babe1babe1babe1babe1babe1babe1babe1babe1babe1babe1babe1babe 0x20 mstore + + 0x05 0x40 mstore + __RIGHTPAD(0xbabe2babe2) 0x60 mstore + + 0x40 0x00 + CONCAT_MEMORY() + + dup1 mload + 0x00 SET_STOR() + + dup1 0x20 add mload + 0x20 SET_STOR() + + dup1 0x40 add mload + 0x40 SET_STOR() + + stop +} + +#define macro CONCAT_MEMORY_AND_SET5() = takes (0) returns (0) { + pop + + 0x0a 0x00 mstore + __RIGHTPAD(0xbabe1babe1babe1babe1) 0x20 mstore + + 0x05 0x40 mstore + __RIGHTPAD(0xbabe2babe2) 0x60 mstore + + 0x40 0x00 + CONCAT_MEMORY() + + dup1 mload + 0x00 SET_STOR() + + dup1 0x20 add mload + 0x20 SET_STOR() + + stop +} + +#define macro CONCAT_MEMORY_AND_SET6() = takes (0) returns (0) { + pop + + // don't need to be % 0x20 + 0x0a 0x05 mstore + __RIGHTPAD(0xbabe1babe1babe1babe1) 0x25 mstore + + 0x05 0x48 mstore + __RIGHTPAD(0xbabe2babe2) 0x68 mstore + + 0x48 0x05 + CONCAT_MEMORY() // [pos] + + dup1 mload // [len, pos] + 0x00 SET_STOR() // [pos] + + dup1 0x20 add mload // [babe1, pos] + 0x20 SET_STOR() // [pos] + + stop +} + +#define macro SLICE_MEMORY_AND_SET1() = takes (0) returns (0) { + pop + + 0x20 0x00 mstore + 0xbabe1babe1babe1babe1babe1babe1babe1babe1babe1babe1babe1babe1babe 0x20 mstore + + 0x10 0x00 0x00 // [mem_ptr, start, length] + SLICE_MEMORY() // [slice_ptr] + + dup1 mload + 0x00 SET_STOR() + + dup1 0x20 add mload + 0x20 SET_STOR() + + stop +} + +#define macro SLICE_MEMORY_AND_SET2() = takes (0) returns (0) { + pop + + 0x40 0x00 mstore + 0xbabe1babe1babe1babe1babe1babe1babe1babe1babe1babe1babe1babe1babe 0x20 mstore + 0xbabe2babe2babe2babe2babe2babe2babe2babe2babe2babe2babe2babe2babe 0x40 mstore + + 0x24 0x02 0x00 + SLICE_MEMORY() + + dup1 mload + 0x00 SET_STOR() + + dup1 0x20 add mload + 0x20 SET_STOR() + + dup1 0x40 add mload + 0x40 SET_STOR() + + stop +} + +#define macro SLICE_MEMORY_AND_SET3() = takes (0) returns (0) { + pop + + 0x40 0x07 mstore + 0xbabe1babe1babe1babe1babe1babe1babe1babe1babe1babe1babe1babe1babe 0x27 mstore + __RIGHTPAD(0xbabe2bab) 0x47 mstore + + 0x04 0x20 0x07 + SLICE_MEMORY() + + dup1 mload + 0x00 SET_STOR() + + dup1 0x20 add mload + 0x20 SET_STOR() + + stop +} + +#define macro MAIN() = takes (0) returns (0) { + 0x00 calldataload 0xE0 shr + dup1 __FUNC_SIG("concatMemoryAndSet1()") eq concatMemoryAndSet1 jumpi + dup1 __FUNC_SIG("concatMemoryAndSet2()") eq concatMemoryAndSet2 jumpi + dup1 __FUNC_SIG("concatMemoryAndSet3()") eq concatMemoryAndSet3 jumpi + dup1 __FUNC_SIG("concatMemoryAndSet4()") eq concatMemoryAndSet4 jumpi + dup1 __FUNC_SIG("concatMemoryAndSet5()") eq concatMemoryAndSet5 jumpi + dup1 __FUNC_SIG("concatMemoryAndSet6()") eq concatMemoryAndSet6 jumpi + dup1 __FUNC_SIG("sliceMemoryAndSet1()") eq sliceMemoryAndSet1 jumpi + dup1 __FUNC_SIG("sliceMemoryAndSet2()") eq sliceMemoryAndSet2 jumpi + dup1 __FUNC_SIG("sliceMemoryAndSet3()") eq sliceMemoryAndSet3 jumpi + + 0x00 0x00 revert + + concatMemoryAndSet1: + CONCAT_MEMORY_AND_SET1() + concatMemoryAndSet2: + CONCAT_MEMORY_AND_SET2() + concatMemoryAndSet3: + CONCAT_MEMORY_AND_SET3() + concatMemoryAndSet4: + CONCAT_MEMORY_AND_SET4() + concatMemoryAndSet5: + CONCAT_MEMORY_AND_SET5() + concatMemoryAndSet6: + CONCAT_MEMORY_AND_SET6() + sliceMemoryAndSet1: + SLICE_MEMORY_AND_SET1() + sliceMemoryAndSet2: + SLICE_MEMORY_AND_SET2() + sliceMemoryAndSet3: + SLICE_MEMORY_AND_SET3() +} + + +/// @title Bytes +/// @notice SPDX-License-Identifier: MIT +/// @author Franfran +/// @notice Low-level operations on bytes +/// @notice Adapted from BytesLib (https://github.com/GNSPS/solidity-bytes-utils/blob/master/contracts/BytesLib.sol) + +/// @notice Concatenate two bytes arrays +/// @notice Takes in two pointers of the bytes to concatenate that must be sorted +/// @return Pointer of the new appended concatenated bytes array in the memory +/// @dev Warning! This assumes that the pointer in the memory of the second bytes chunk is after mem_ptr1 + 0x20 +#define macro CONCAT_MEMORY() = takes(2) returns(1) { + // input stack // [mem_ptr1, mem_ptr2] + + // setup stack and memory for the next iterations + dup2 mload swap1 // [mem_ptr1, len2, mem_ptr2] + msize swap1 // [mem_ptr1, free_loc_pos, len2, mem_ptr2] + dup1 mload dup4 // [len2, len1, mem_ptr1, free_loc_pos, len2, mem_ptr2] + dup2 add msize mstore // [len1, mem_ptr1, free_loc_pos, len2, mem_ptr2] + + swap1 0x20 add // [index(i), len1, free_loc_pos, len2, mem_ptr2] + msize // [index(j), index(i), len1, free_loc_pos, len2, mem_ptr2] + swap2 0x00 // [is_sec_loop, len1, index(i), index(j), free_loc_pos, len2, mem_ptr2] + + // i is the index where we get (mload) the array element and j is the index where we store (mstore) the array at j + loop: // [is_sec_loop, len_left, index(i), index(j), free_loc_pos, len2, mem_ptr2] + dup2 iszero empty_slot jumpi // [is_sec_loop, len_left, index(i), index(j), free_loc_pos, len2, mem_ptr2] + + dup3 mload // [word, is_sec_loop, len_left, index(i), index(j), free_loc_pos, len2, mem_ptr2] + dup3 0x20 gt iszero // [is_full_slot, word, is_sec_loop, len_left, index(i), index(j), free_loc_pos, len2, mem_ptr2] + full_slot jumpi // [word, is_sec_loop, len_left, index(i), index(j), free_loc_pos, len2, mem_ptr2] + + // else it's not a full slot, we're hitting an end. Then clean memory slot and update j with a partial length + dup3 0x20 sub // [pad_len, word, is_sec_loop, len_left, index(i), index(j), free_loc_pos, len2, mem_ptr2] + 0x08 mul swap1 dup2 // [shift, word, shift, is_sec_loop, len_left, index(i), index(j), free_loc_pos, len2, mem_ptr2] + shr // [left_padded_word, shift, is_sec_loop, len_left, index(i), index(j), free_loc_pos, len2, mem_ptr2] + swap1 shl // [clean_word, is_sec_loop, len_left, index(i), index(j), free_loc_pos, len2, mem_ptr2] + dup5 mstore // [is_sec_loop, len_left, index(i), index(j), free_loc_pos, len2, mem_ptr2] + swap3 add swap2 // [is_sec_loop, index(i), index(j + 1), free_loc_pos, len2, mem_ptr2] + + // here we check if current loop is for the 2nd array + swap1 pop // [is_sec_loop, index(j + 1), free_loc_pos, len2, mem_ptr2] + iszero bridge jumpi // [index(j + 1), free_loc_pos, len2, mem_ptr2] + pop break jump // [free_loc_pos, len2, mem_ptr2] + + empty_slot: // [is_sec_loop, len_left, index(i), index(j), free_loc_pos, len2, mem_ptr2] + swap2 pop pop // [is_sec_loop, index(j), free_loc_pos, len2, mem_ptr2] + iszero bridge jumpi // [index(j), free_loc_pos, len2, mem_ptr2] + pop break jump // [free_loc_pos, len2, mem_ptr2] + + bridge: // [index(j), free_loc_pos, len2, mem_ptr2] + dup4 0x20 add // [index(i), index(j), free_loc_pos, len2, mem_ptr2] + dup5 // [len2, index(i), index(j), free_loc_pos, len2, mem_ptr2] + 0x01 // [is_sec_loop, len2, index(i), index(j), free_loc_pos, len2, mem_ptr2] + loop jump + + full_slot: // [word, is_sec_loop, len_left, index(i), index(j), free_loc_pos, len2, mem_ptr2] + dup5 mstore // [is_sec_loop, len_left, index(i), index(j), free_loc_pos, len2, mem_ptr2] + swap1 0x20 swap1 sub // [len_left - 0x20, is_sec_loop, index(i), index(j), free_loc_pos, len2, mem_ptr2] + swap2 0x20 add // [index(i + 1), is_sec_loop, len_left - 0x20, index(j), free_loc_pos, len2, mem_ptr2] + swap3 0x20 add // [index(j + 1), is_sec_loop, len_left - 0x20, index(i + 1), free_loc_pos, len2, mem_ptr2] + swap3 swap2 swap1 // [is_sec_loop, len_left - 0x20, index(i + 1), index(j + 1), free_loc_pos, len2, mem_ptr2] + loop jump + + break: // [free_loc_pos, len2, mem_ptr2] + swap2 pop pop // [free_loc_pos] +} + +/// @param Pointer in memory of the start of the bytes array +/// @param Start position of the slice relative to the array +/// @param Length of the output slice +/// @return Pointer of the new appended concatenated bytes array in the memory +/// @dev Warning! This assumes that the length of the output slice is less or equal the length of the bytes array (bytes.len < slice.len) +/// @dev Warning! This assumes that the start of the bytes array is not out of bounds (start < len + mem_ptr) +#define macro SLICE_MEMORY() = takes(3) returns(1) { + // input stack // [mem_ptr, start, length] + + msize dup4 msize mstore // [free_loc_pos, mem_ptr, start, length] + msize swap4 // [length, free_loc_pos, mem_ptr, start, index(j)] + // index(i) = mem_ptr + start + 0x20 + swap1 swap3 // [start, length, mem_ptr, free_loc_pos, index(j)] + swap1 swap2 // [mem_ptr, start, length, free_loc_pos, index(j)] + 0x20 add add // [index(i), length, free_loc_pos, index(j)] + + // we load our slice chunk at i and store it in a free memory location at j + loop: // [index(i), length_left, free_loc_pos, index(j)] + dup1 mload // [slice_chunk, index(i), length_left, free_loc_pos, index(j)] + + // if current is not full slot, then load the last bytes and break + 0x20 dup4 lt // [is_not_full_slot, slice_chunk, index(i), length_left, free_loc_pos, index(j)] + break jumpi // [slice_chunk, index(i), length_left, free_loc_pos, index(j)] + + dup5 mstore // [index(i), length_left, free_loc_pos, index(j)] + + 0x20 add swap3 // [free_loc, length_left, free_loc_pos, index(i+1)] + 0x20 add swap3 // [index(i+1), length_left, free_loc_pos, free_loc + 1] + swap1 0x20 // [0x20, length_left, index(i+1), free_loc_pos, free_loc + 1] + swap1 sub // [length_left - 1, index(i+1), free_loc_pos, free_loc + 1] + swap1 // [index(i+1), length_left - 1, free_loc_pos, free_loc + 1] + + loop jump + + break: // [slice_chunk, index(i), length, free_loc_pos, index(j)] + // store the remaining length + dup3 0x20 sub // [zero_length, slice_chunk, index(i), length, free_loc_pos, index(j)] + 0x08 mul swap1 dup2 // [shift, slice_chunk, shift, index(i), length, free_loc_pos, index(j)] + shr // [left_pad_slice, shift, index(i), length, free_loc_pos, index(j)] + swap1 shl // [slice_chunk, index(i), length, free_loc_pos, index(j)] + dup5 mstore // [index(i), length, free_loc_pos, index(j)] + + pop pop swap1 pop // [free_loc_pos] +} diff --git a/src/math/__TEMP__agffsybhummgrdmhvrzqoxrnkhupycfeMath.huff b/src/math/__TEMP__agffsybhummgrdmhvrzqoxrnkhupycfeMath.huff new file mode 100644 index 00000000..1c65a83e --- /dev/null +++ b/src/math/__TEMP__agffsybhummgrdmhvrzqoxrnkhupycfeMath.huff @@ -0,0 +1,319 @@ + +#define macro SQRT_WRAPPER() = { + 0x04 calldataload + SQRT() + 0x00 mstore + 0x20 0x00 return +} + +#define macro MAX_WRAPPER() = { + 0x04 calldataload + 0x24 calldataload + MAX() + 0x00 mstore + 0x20 0x00 return +} + +#define macro MIN_WRAPPER() = { + 0x04 calldataload + 0x24 calldataload + MIN() + 0x00 mstore + 0x20 0x00 return +} + +#define macro AVG_WRAPPER() = { + 0x04 calldataload + 0x24 calldataload + AVG() + 0x00 mstore + 0x20 0x00 return +} + +#define macro CEIL_DIV_WRAPPER() = { + 0x24 calldataload + 0x04 calldataload + CEIL_DIV() + 0x00 mstore + 0x20 0x00 return +} + +#define macro MAIN() = { + 0x00 calldataload 0xE0 shr + dup1 __FUNC_SIG(sqrt) eq sqrt jumpi + dup1 __FUNC_SIG(max) eq max jumpi + dup1 __FUNC_SIG(min) eq min jumpi + dup1 __FUNC_SIG(average) eq average jumpi + dup1 __FUNC_SIG(ceilDiv) eq ceilDiv jumpi + + 0x00 0x00 revert + + sqrt: + SQRT_WRAPPER() + max: + MAX_WRAPPER() + min: + MIN_WRAPPER() + average: + AVG_WRAPPER() + ceilDiv: + CEIL_DIV_WRAPPER() +} + + +/// @title Math +/// @notice SPDX-License-Identifier: MIT +/// @author manas +/// @author kadenzipfel +/// @notice Math module over Solidity's arithmetic operations +/// @notice Adapted from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/math/Math.sol) + +#include "../utils/Errors.huff" + +// Interface +#define function sqrt(uint256) pure returns(uint256) +#define function max(uint256, uint256) pure returns(uint256) +#define function min(uint256, uint256) pure returns(uint256) +#define function average(uint256, uint256) pure returns(uint256) +#define function ceilDiv(uint256, uint256) pure returns(uint256) + +// Negative 1 in two's compliment +#define constant NEG1 = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + +/// @notice Calculates the square root of a stack input +#define macro SQRT() = takes (1) returns (1) { + // input stack // [num] + // if num == 0 return 0 + dup1 // [number, number] + iszero // [is_zero, number] + is_zero jumpi + + // assign stack vars + dup1 // [x, num] + 0x01 // [result, x, num] + + // if (x >> 128 > 0) { + // x >>= 128; + // result <<= 64; + // } + dup2 // [x, result, x, num] + 0x80 shr // [x >> 128, result, x, num] + dup1 // [x >> 128, x >> 128, result, x, num] + iszero // [x >> 128 == 0, x >> 128, result, x, num] + sh_128_0 jumpi + swap1 0x40 shl // [result, x >> 128, x, num] + swap1 swap2 // [x, result, x >> 128, num] + sh_128_0: + pop + + // if (x >> 64 > 0) { + // x >>= 64; + // result <<= 32; + // } + dup2 // [x, result, x, num] + 0x40 shr // [x >> 64, result, x, num] + dup1 // [x >> 64, x >> 64, result, x, num] + iszero // [x >> 64 == 0, x >> 64, result, x, num] + sh_64_0 jumpi + swap1 0x20 shl // [result, x >> 64, x, num] + swap1 swap2 // [x, result, x >> 64, num] + sh_64_0: + pop + + // if (x >> 32 > 0) { + // x >>= 32; + // result <<= 16; + // } + dup2 // [x, result, x, num] + 0x20 shr // [x >> 32, result, x, num] + dup1 // [x >> 32, x >> 32, result, x, num] + iszero // [x >> 32 == 0, x >> 32, result, x, num] + sh_32_0 jumpi + swap1 0x10 shl // [result, x >> 32, x, num] + swap1 swap2 // [x, result, x >> 32, num] + sh_32_0: + pop + + // if (x >> 16 > 0) { + // x >>= 16; + // result <<= 8; + // } + dup2 // [x, result, x, num] + 0x10 shr // [x >> 16, result, x, num] + dup1 // [x >> 16, x >> 16, result, x, num] + iszero // [x >> 16 == 0, x >> 16, result, x, num] + sh_16_0 jumpi + swap1 0x08 shl // [result, x >> 16, x, num] + swap1 swap2 // [x, result, x >> 16, num] + sh_16_0: + pop + + // if (x >> 8 > 0) { + // x >>= 8; + // result <<= 4; + // } + dup2 // [x, result, x, num] + 0x08 shr // [x >> 8, result, x, num] + dup1 // [x >> 8, x >> 8, result, x, num] + iszero // [x >> 8 == 0, x >> 8, result, x, num] + sh_8_0 jumpi + swap1 0x04 shl // [result, x >> 8, x, num] + swap1 swap2 // [x, result, x >> 8, num] + sh_8_0: + pop + + // if (x >> 4 > 0) { + // x >>= 4; + // result <<= 2; + // } + dup2 // [x, result, x, num] + 0x04 shr // [x >> 4, result, x, num] + dup1 // [x >> 4, x >> 4, result, x, num] + iszero // [x >> 4 == 0, x >> 4, result, x, num] + sh_4_0 jumpi + swap1 0x02 shl // [result, x >> 4, x, num] + swap1 swap2 // [x, result, x >> 4, num] + sh_4_0: + pop + + // if (x >> 2 > 0) { + // x >>= 2; + // result <<= 1; + // } + dup2 // [x, result, x, num] + 0x02 shr // [x >> 2, result, x, num] + dup1 // [x >> 2, x >> 2, result, x, num] + iszero // [x >> 2 == 0, x >> 2, result, x, num] + sh_2_0 jumpi + swap1 0x01 shl // [result, x >> 2, x, num] + swap1 swap2 // [x, result, x >> 2, num] + sh_2_0: + pop + + // result = (result + num / result) >> 1; + dup1 // [result, result, x, num] + dup4 // [num, result, result, x, num] + div // [num / result, result x, num] + add // [result + num / result, x, num] + 0x01 shr // [result, x, num] + + // result = (result + num / result) >> 1; + dup1 // [result, result, x, num] + dup4 // [num, result, result, x, num] + div // [num / result, result, x, num] + add // [result + num / result, x, num] + 0x01 shr // [result, x, num] + + // result = (result + num / result) >> 1; + dup1 // [result, result, x, num] + dup4 // [num, result, result, x, num] + div // [num / result, result, x, num] + add // [result + num / result, x, num] + 0x01 shr // [result, x, num] + + // result = (result + num / result) >> 1; + dup1 // [result, result, x, num] + dup4 // [num, result, result, x, num] + div // [num / result, result, x, num] + add // [result + num / result, x, num] + 0x01 shr // [result, x, num] + + // result = (result + num / result) >> 1; + dup1 // [result, result, x, num] + dup4 // [num, result, result, x, num] + div // [num / result, result, x, num] + add // [result + num / result, x, num] + 0x01 shr // [result, x, num] + + // result = (result + num / result) >> 1; + dup1 // [result, result, x, num] + dup4 // [num, result, result, x, num] + div // [num / result, result, x, num] + add // [result + num / result, x, num] + 0x01 shr // [result, x, num] + + // result = (result + num / result) >> 1; + dup1 // [result, result, x, num] + dup4 // [num, result, result, x, num] + div // [num / result, result, x, num] + add // [result + num / result, x, num] + 0x01 shr // [result, x, num] + + // result = min(result, num / result) + dup1 // [result, result, x, num] + swap3 // [num, result, x, result] + div // [num / result, x, result] + swap2 swap1 pop // [result, num / result] + MIN() + + is_zero: +} + +/// @notice Returns the maximum value of two values on the stack +#define macro MAX() = takes (2) returns (1) { + // input stack: // [num1, num2] + dup2 // [num2, num1, num2] + dup2 // [num1, num2, num1, num2] + lt // [is_less_than, num1, num2] + + less_than jumpi + swap1 // [num1, num2] + + less_than: + pop // [max(num2, num1)] +} + +/// @notice Returns the ceiling of the division of two values on the stack +#define macro CEIL_DIV() = takes (2) returns (1) { + // input stack: // [num1, num2] + dup1 iszero // [is_zero, num1, num2] + if_zero jumpi + + dup2 iszero // [is_zero, num1, num2] + divide_by_zero jumpi + + 0x01 // [1, num1, num2] + swap1 // [num1, 1, num1] + sub // [num1 - 1, num2] + div 0x01 add // [((num1 - 1) / num2) + 1] + dest jump + + divide_by_zero: + [DIVIDE_BY_ZERO] PANIC() + + if_zero: + swap1 // [num2, num1] + pop // [num1] + + dest: +} + +/// @notice Returns the minimum value of two values on the stack +#define macro MIN() = takes (2) returns (1) { + // input stack: // [num1, num2] + dup2 dup2 gt // [is_greater_than, num1, num2] + + greater_than jumpi + swap1 // [num2, num1] + + greater_than: + pop // [min(num1, num2)] +} + +/// @notice Returns the average of two values on the stack +#define macro AVG() = takes (2) returns (1) { + // input stack: // [num1, num2] + dup2 dup2 and // [num1 & num2, num1, num2] + swap2 // [num2, num1, num1 & num2] + xor // [num2 ^ num1, num1 & num2] + 0x02 swap1 div // [num2 ^ num1 / 2, num1 & num2] + add // [sum] +} + +/// @notice Unsafely subtracts 1 from a uint256 using the 2's complement representation +#define macro UNSAFE_SUB() = takes (1) returns (1) { + // Input Stack: [x] + // Output Stack: [x - 1] + + [NEG1] add // [x - 1] +} \ No newline at end of file diff --git a/src/math/__TEMP__gtvxtadnkjdmxsyyimfngsleoolwhcqtSafeMath.huff b/src/math/__TEMP__gtvxtadnkjdmxsyyimfngsleoolwhcqtSafeMath.huff new file mode 100644 index 00000000..8ac2256c --- /dev/null +++ b/src/math/__TEMP__gtvxtadnkjdmxsyyimfngsleoolwhcqtSafeMath.huff @@ -0,0 +1,153 @@ + +// Wrapper methods (for testing) +#define macro SAFE_ADD_WRAPPER() = takes (0) returns (0) { + 0x04 calldataload // [num1] + 0x24 calldataload // [num2, num1] + SAFE_ADD() // [result] + 0x00 mstore // [] + 0x20 0x00 return // [] +} + +#define macro SAFE_SUB_WRAPPER() = takes (0) returns (0) { + 0x04 calldataload // [num1] + 0x24 calldataload // [num2, num1] + swap1 // [num1, num2] + SAFE_SUB() // [result] + 0x00 mstore // [] + 0x20 0x00 return // [] +} + +#define macro SAFE_MUL_WRAPPER() = takes (0) returns (0) { + 0x04 calldataload // [num1] + 0x24 calldataload // [num2, num1] + SAFE_MUL() // [result] + 0x00 mstore // [] + 0x20 0x00 return // [] +} + +#define macro SAFE_DIV_WRAPPER() = takes (0) returns (0) { + 0x04 calldataload // [num1] + 0x24 calldataload // [num2, num1] + swap1 // [num1, num2] + SAFE_DIV() // [result] + 0x00 mstore // [] + 0x20 0x00 return // [] +} + +#define macro SAFE_MOD_WRAPPER() = takes (0) returns (0) { + 0x04 calldataload // [num1] + 0x24 calldataload // [num2, num1] + swap1 // [num1, num2] + SAFE_MOD() // [result] + 0x00 mstore // [] + 0x20 0x00 return // [] +} + +// Main +#define macro MAIN() = takes (0) returns (0) { + 0x00 calldataload 0xE0 shr + dup1 __FUNC_SIG(safeAdd) eq safe_add jumpi + dup1 __FUNC_SIG(safeSub) eq safe_sub jumpi + dup1 __FUNC_SIG(safeMul) eq safe_mul jumpi + dup1 __FUNC_SIG(safeDiv) eq safe_div jumpi + dup1 __FUNC_SIG(safeMod) eq safe_mod jumpi + + 0x00 0x00 revert + + safe_add: + SAFE_ADD_WRAPPER() + safe_sub: + SAFE_SUB_WRAPPER() + safe_mul: + SAFE_MUL_WRAPPER() + safe_div: + SAFE_DIV_WRAPPER() + safe_mod: + SAFE_MOD_WRAPPER() +} + +/// @title SafeMath +/// @notice SPDX-License-Identifier: MIT +/// @author kadenzipfel +/// @notice Math module over Solidity's arithmetic operations with safety checks +/// @notice Adapted from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/math/SafeMath.sol) + +#include "../utils/Errors.huff" + +// Interface +#define function safeAdd(uint256,uint256) pure returns (uint256) +#define function safeSub(uint256,uint256) pure returns (uint256) +#define function safeMul(uint256,uint256) pure returns (uint256) +#define function safeDiv(uint256,uint256) pure returns (uint256) +#define function safeMod(uint256,uint256) pure returns (uint256) + +/// @notice Adds two numbers and reverts on overflow +#define macro SAFE_ADD() = takes (2) returns (1) { + // input stack // [num1, num2] + dup2 // [num2, num1, num2] + add // [result, num2] + dup1 // [result, result, num2] + swap2 // [num2, result, result] + gt // [is_overflow, result] + iszero // [is_not_overflow, result] + is_not_overflow jumpi // [result] + [ARITHMETIC_OVERFLOW] PANIC() + is_not_overflow: // [result] +} + +/// @notice Subtracts two numbers and reverts on underflow +#define macro SAFE_SUB() = takes (2) returns (1) { + // input stack // [num1, num2] + dup1 // [num1, num1, num2] + dup3 // [num2, num1, num1, num2] + gt // [is_underflow, num1, num2] + iszero // [is_not_underflow, num1, num2] + is_not_underflow jumpi // [num1, num2] + [ARITHMETIC_OVERFLOW] PANIC() + is_not_underflow: // [num1, num2] + sub // [result] +} + +/// @notice Multiplies two numbers and reverts on overflow +#define macro SAFE_MUL() = takes (2) returns (1) { + // input stack // [num1, num2] + dup1 // [num1, num1, num2] + is_not_zero jumpi // [num1, num2] + mul // [result] + 0x01 is_not_overflow jumpi + is_not_zero: // [num1, num2] + dup2 // [num2, num1, num2] + dup2 // [num1, num2, num1, num2] + mul // [result, num1, num2] + swap1 // [num1, result, num2] + dup2 // [result, num1, result, num2] + div // [div_check, result, num2] + swap1 // [result, div_check, num2] + swap2 // [num2, div_check, result] + eq // [is_not_overflow, result] + is_not_overflow jumpi // [result] + [ARITHMETIC_OVERFLOW] PANIC() + is_not_overflow: +} + +/// @notice Divides two numbers and reverts on division by zero +#define macro SAFE_DIV() = takes (2) returns (1) { + // input stack // [num1, num2] + 0x00 dup3 // [num2, 0, num1, num2] + gt // [is_not_div_zero, num1, num2] + is_not_div_zero jumpi + [DIVIDE_BY_ZERO] PANIC() + is_not_div_zero: + div // [result] +} + +/// @notice Divides two numbers and reverts on division by zero or modulo zero +#define macro SAFE_MOD() = takes (2) returns (1) { + // input stack // [num1, num2] + 0x00 dup3 // [num2, 0, num1, num2] + gt // [is_not_mod_zero, num1, num2] + is_not_mod_zero jumpi + [ARITHMETIC_OVERFLOW] PANIC() + is_not_mod_zero: + mod // [result] +} \ No newline at end of file diff --git a/src/math/__TEMP__hbpqkpduhnyeazoevkblfjmhdomwtqwoFixedPointMath.huff b/src/math/__TEMP__hbpqkpduhnyeazoevkblfjmhdomwtqwoFixedPointMath.huff new file mode 100644 index 00000000..323bcc19 --- /dev/null +++ b/src/math/__TEMP__hbpqkpduhnyeazoevkblfjmhdomwtqwoFixedPointMath.huff @@ -0,0 +1,1093 @@ +#define function mulDivDown(uint256,uint256,uint256) pure returns(uint256) +#define function mulDivUp(uint256,uint256,uint256) pure returns(uint256) +#define function mulWadDown(uint256,uint256) pure returns(uint256) +#define function mulWadUp(uint256,uint256) pure returns(uint256) +#define function divWadDown(uint256,uint256) pure returns(uint256) +#define function divWadUp(uint256,uint256) pure returns(uint256) +#define function rpow(uint256,uint256,uint256) pure returns(uint256) +#define function expWad(int256) pure returns(int256) +#define function powWad(int256,int256) pure returns(int256) +#define function lnWad(int256) pure returns(int256) +#define function sqrt(uint256) pure returns(uint256) +#define function log2(uint256) pure returns(uint256) +#define function cbrt(uint256) pure returns(uint256) + +#define macro MUL_DIV_DOWN_WRAPPER(fail) = takes (0) returns (0) { + 0x44 calldataload // [denominator] + 0x24 calldataload // [y, denominator] + 0x04 calldataload // [x, y, denominator] + MUL_DIV_DOWN(fail) // [result] + 0x00 mstore // [] + 0x20 0x00 return +} + +#define macro MUL_DIV_UP_WRAPPER(fail) = takes (0) returns (0) { + 0x44 calldataload // [denominator] + 0x24 calldataload // [y, denominator] + 0x04 calldataload // [x, y, denominator] + MUL_DIV_UP(fail) // [result] + 0x00 mstore // [] + 0x20 0x00 return +} + +#define macro MUL_WAD_DOWN_WRAPPER(fail) = takes (0) returns (0) { + 0x24 calldataload // [y] + 0x04 calldataload // [x, y] + MUL_WAD_DOWN(fail) // [result] + 0x00 mstore // [] + 0x20 0x00 return +} + +#define macro MUL_WAD_UP_WRAPPER(fail) = takes (0) returns (0) { + 0x24 calldataload // [y] + 0x04 calldataload // [x, y] + MUL_WAD_UP(fail) // [result] + 0x00 mstore // [] + 0x20 0x00 return +} + +#define macro DIV_WAD_DOWN_WRAPPER(fail) = takes (0) returns (0) { + 0x24 calldataload // [y] + 0x04 calldataload // [x, y] + DIV_WAD_DOWN(fail) // [result] + 0x00 mstore // [] + 0x20 0x00 return +} + +#define macro DIV_WAD_UP_WRAPPER(fail) = takes (0) returns (0) { + 0x24 calldataload // [y] + 0x04 calldataload // [x, y] + DIV_WAD_UP(fail) // [result] + 0x00 mstore // [] + 0x20 0x00 return +} + +#define macro RPOW_WRAPPER(fail) = takes (0) returns (0) { + 0x44 calldataload // [scalar] + 0x24 calldataload // [n, scalar] + 0x04 calldataload // [x, n, scalar] + RPOW(fail) // [result] + 0x00 mstore // [] + 0x20 0x00 return +} + +#define macro EXP_WAD_WRAPPER(fail) = takes (0) returns (0) { + 0x04 calldataload // [x] + EXP_WAD(fail) // [result] + 0x00 mstore + 0x20 0x00 return +} + +#define macro LN_WAD_WRAPPER(fail) = takes (0) returns (0) { + 0x04 calldataload // [x] + LN_WAD(fail) // [result] + 0x00 mstore + 0x20 0x00 return +} + +#define macro POW_WAD_WRAPPER(fail) = takes (0) returns (0) { + 0x24 calldataload // [y] + 0x04 calldataload // [x, y] + POW_WAD(fail) // [result] + 0x00 mstore // [] + 0x20 0x00 return +} + +#define macro SQRT_WRAPPER() = takes (0) returns (0) { + 0x04 calldataload // [x] + SQRT() // [result] + 0x00 mstore + 0x20 0x00 return +} + +#define macro LOG_2_WRAPPER(fail) = takes (0) returns (0) { + 0x04 calldataload // [x] + LOG_2(fail) // [result] + 0x00 mstore + 0x20 0x00 return +} + +#define macro CBRT_WRAPPER() = takes (0) returns (0) { + 0x04 calldataload + CBRT() + 0x00 mstore + 0x20 0x00 return +} + +#define macro MAIN() = takes (0) returns (0) { + pc calldataload 0xE0 shr + dup1 __FUNC_SIG(mulDivDown) eq mulDivDown jumpi + dup1 __FUNC_SIG(mulDivUp) eq mulDivUp jumpi + dup1 __FUNC_SIG(mulWadDown) eq mulWadDown jumpi + dup1 __FUNC_SIG(mulWadUp) eq mulWadUp jumpi + dup1 __FUNC_SIG(divWadDown) eq divWadDown jumpi + dup1 __FUNC_SIG(divWadUp) eq divWadUp jumpi + dup1 __FUNC_SIG(rpow) eq rpow jumpi + dup1 __FUNC_SIG(expWad) eq expWad jumpi + dup1 __FUNC_SIG(lnWad) eq lnWad jumpi + dup1 __FUNC_SIG(powWad) eq powWad jumpi + dup1 __FUNC_SIG(sqrt) eq sqrt jumpi + dup1 __FUNC_SIG(log2) eq logTwo jumpi + dup1 __FUNC_SIG(cbrt) eq cbrt jumpi + + + fail: + 0x00 0x00 revert + mulDivDown: + MUL_DIV_DOWN_WRAPPER(fail) + mulDivUp: + MUL_DIV_UP_WRAPPER(fail) + mulWadDown: + MUL_WAD_DOWN_WRAPPER(fail) + mulWadUp: + MUL_WAD_UP_WRAPPER(fail) + divWadDown: + DIV_WAD_DOWN_WRAPPER(fail) + divWadUp: + DIV_WAD_UP_WRAPPER(fail) + rpow: + RPOW_WRAPPER(fail) + expWad: + EXP_WAD_WRAPPER(fail) + lnWad: + LN_WAD_WRAPPER(fail) + powWad: + POW_WAD_WRAPPER(fail) + sqrt: + SQRT_WRAPPER() + logTwo: + LOG_2_WRAPPER(fail) + cbrt: + CBRT_WRAPPER() +} + +/// @title FixedPointMath +/// @notice SPDX-License-Identifier: MIT +/// @author clabby +/// @notice Minimal module for fixed-point number arithmetic +/// @notice Adapted from Solmate (https://github.com/transmissions11/solmate/blob/v7/src/utils/FixedPointMathLib.sol) + +#define constant WAD = 0x0de0b6b3a7640000 +#define constant DAY = 0x15180 + +//////////////////////////////////////////////////////////////// +// SIMPLIFIED FIXED POINT OPERATIONS // +//////////////////////////////////////////////////////////////// + +// https://github.com/transmissions11/solmate/blob/v7/src/utils/FixedPointMathLib.sol#L13 +#define macro MUL_WAD_DOWN(fail) = takes (2) returns (1) { + // Input stack: [x, y] + [WAD] // [WAD, x, y] + ARRANGE_STACK_MULWAD() // [x, y, WAD] + MUL_DIV_DOWN(fail) // [result] +} + +// https://github.com/transmissions11/solmate/blob/v7/src/utils/FixedPointMathLib.sol#L17 +#define macro MUL_WAD_UP(fail) = takes (2) returns (1) { + // Input stack: [x, y] + [WAD] // [WAD, x, y] + ARRANGE_STACK_MULWAD() // [x, y, WAD] + MUL_DIV_UP(fail) // [result] +} + +// https://github.com/transmissions11/solmate/blob/v7/src/utils/FixedPointMathLib.sol#L21 +#define macro DIV_WAD_DOWN(fail) = takes (2) returns (1) { + // Input stack: [x, y] + [WAD] // [WAD, x, y] + ARRANGE_STACK_DIVWAD() // [x, WAD, y] + MUL_DIV_DOWN(fail) +} + +// https://github.com/transmissions11/solmate/blob/v7/src/utils/FixedPointMathLib.sol#L25 +#define macro DIV_WAD_UP(fail) = takes (2) returns (1) { + // Input stack: [x, y] + [WAD] // [WAD, x, y] + ARRANGE_STACK_DIVWAD() // [x, WAD, y] + MUL_DIV_UP(fail) // [result] +} + +// https://github.com/transmissions11/solmate/blob/v7/src/utils/FixedPointMathLib.sol#L34 +#define macro EXP_WAD(fail) = takes (1) returns (1) { + // Input stack: [x] + + // When the result is < 0.5 we return zero. This happens when + // x <= floor(log(0.5e18) * 1e18) ~ -42e18 + 0xfffffffffffffffffffffffffffffffffffffffffffffffdb731c958f34d94c1 + dup2 // [x, 0xfff..., x] + sgt iszero // [x <= 0xfff..., x] + ret_zero jumpi // [x] + + // When the result is > (2**255 - 1) / 1e18 we can not represent it as an + // int. This happens when x >= floor(log((2**255 - 1) / 1e18) * 1e18) ~ 135. + 0x0755bf798b4a1bf1e5 // [0x0755bf798b4a1bf1e5, x] + dup2 // [x, 0x0755bf798b4a1bf1e5, x] + slt iszero // [x >= 0x0755bf798b4a1bf1e5, x] + jumpi // [x] + + // x is now in the range (-42, 136) * 1e18. Convert to (-42, 136) * 2**96 + // for more intermediate precision and a binary basis. This base conversion + // is a multiplication by 1e18 / 2**96 = 5**18 / 2**78. + 0x03782dace9d9 // [0x05 ** 0x12, x] + swap1 // [x, 0x05 ** 0x12] + 0x4e shl // [x << 0x4e, 0x05 ** 0x12] + sdiv // [x << 0x4e / 0x05 ** 0x12] + + // Reduce range of x to (-1/2 ln 2, 1/2 ln 2) * 2**96 by factoring out powers + // of two such that exp(x) = exp(x') * 2**k, where k is an integer. + // Solving this gives k = round(x / log(2)) and x' = x - k * log(2). + 0xb17217f7d1cf79abc9e3b398 + dup2 // [x, 0xb17217f7d1cf79abc9e3b398, x] + 0x60 shl // [x << 96, 0xb17217f7d1cf79abc9e3b398, x] + sdiv // [x << 96 / 0xb17217f7d1cf79abc9e3b398, x] + 0x7ffffff20f9306d2eea00000 // [2**95, x << 96 / 0xb17217f7d1cf79abc9e3b398, x] + add // [2**95 + x << 96 / 0xb17217f7d1cf79abc9e3b398, x] + 0x60 sar // [(2**95 + x << 96 / 0xb17217f7d1cf79abc9e3b398) >> 96, x] + + dup1 // [(2**95 + x << 96 / 0xb17217f7d1cf79abc9e3b398) >> 96, (2**95 + x << 96 / 0xb17217f7d1cf79abc9e3b398) >> 96, x] + 0xb17217f7d1cf79abc9e3b398 + mul // [((2**95 + x << 96 / 0xb17217f7d1cf79abc9e3b398) >> 96) * 0xb17217f7d1cf79abc9e3b398, (2**95 + x << 96 / 0xb17217f7d1cf79abc9e3b398) >> 96, x] + dup3 // [x, ((2**95 + x << 96 / 0xb17217f7d1cf79abc9e3b398) >> 96) * 0xb17217f7d1cf79abc9e3b398, (2**95 + x << 96 / 0xb17217f7d1cf79abc9e3b398) >> 96, x] + sub // [x (new), (2**95 + x << 96 / 0xb17217f7d1cf79abc9e3b398) >> 96, x] + swap2 pop // [k, x] + + // k is in the range [-61, 195]. + + // Evaluate using a (6, 7)-term rational approximation. + // p is made monic, we'll multiply by a scale factor later. + 0x10fe68e7fd37d0007b713f7650 + dup3 // [x, 0x10fe68e7fd37d0007b713f7650, k, x] + add // [y, k, x] + + 0x02d16720577bd19bf614176fe9ea + dup2 dup5 mul // [x * y, 0x02d16720577bd19bf614176fe9ea, y, k, x] + 0x60 sar // [(x * y) >> 0x60, 0x02d16720577bd19bf614176fe9ea, y, k, x] + add // [((x * y) >> 0x60) + 0x02d16720577bd19bf614176fe9ea, y, k, x] + swap1 pop // [y, k, x] + + 0x04a4fd9f2a8b96949216d2255a6c + dup4 dup3 add // [x + y, 0x04a4fd9f2a8b96949216d2255a6c, y, k, x] + sub // [x + y - 0x04a4fd9f2a8b96949216d2255a6c, y, k, x] + + dup2 // [y, x + y - 0x04a4fd9f2a8b96949216d2255a6c, y, k, x] + mul // [y * (x + y - 0x04a4fd9f2a8b96949216d2255a6c), y, k, x] + 0x60 sar // [(y * (x + y - 0x04a4fd9f2a8b96949216d2255a6c)) >> 0x60, y, k, x] + 0x0587f503bb6ea29d25fcb740196450 + add // [p, y, k, x] + + dup4 // [x, p, y, k, x] + mul // [x * p, y, k, x] + 0xd835ebba824c98fb31b83b2ca45c + 0x60 shl // [0xd835ebba824c98fb31b83b2ca45c << 0x60, x * p, y, k, x] + add // [p, y, k, x] + + // We leave p in 2**192 basis so we don't need to scale it back up for the division. + + 0x240c330e9fb2d9cbaf0fd5aafc + dup5 sub // [q, p, y, k, x] + + dup5 mul // [x * q, p, y, k, x] + 0x60 sar // [(x * q) >> 0x60, p, y, k, x] + 0x0277594991cfc85f6e2461837cd9 + add // [q, p, y, k, x] + + dup5 mul // [x * q, p, y, k, x] + 0x60 sar // [(x * q) >> 0x60, p, y, k, x] + 0x1a521255e34f6a5061b25ef1c9c4 swap1 + sub // [q, p, y, k, x] + + dup5 mul // [x * q, p, y, k, x] + 0x60 sar // [(x * q) >> 0x60, p, y, k, x] + 0xb1bbb201f443cf962f1a1d3db4a5 + add // [q, p, y, k, x] + + dup5 mul // [x * q, p, y, k, x] + 0x60 sar // [(x * q) >> 0x60, p, y, k, x] + 0x02c72388d9f74f51a9331fed693f15 swap1 + sub // [q, p, y, k, x] + + dup5 mul // [x * q, p, y, k, x] + 0x60 sar // [(x * q) >> 0x60, p, y, k, x] + 0x05180bb14799ab47a8a8cb2a527d57 + add // [q, p, y, k, x] + + // The q polynomial won't have zeros in the domain as all its roots are complex. + // No scaling is necessary because p is already 2**96 too large. + swap1 sdiv // [p / q (r), y, k, x] + + // r should be in the range (0.09, 0.25) * 2**96. + + // We now need to multiply r by: + // * the scale factor s = ~6.031367120. + // * the 2**k factor from the range reduction. + // * the 1e18 / 2**96 factor for base conversion. + // We do this all at once, with an intermediate result in 2**213 + // basis, so the final right shift is always by a positive amount. + + 0x029d9dc38563c32e5c2f6dc192ee70ef65f9978af3 + mul // [0x029d9... * r, y, k, x] + dup3 // [k, 0x029d9... * r, y, k, x] + 0xc3 sub // [0xc3 - k, 0x029d9... * r, y, k, x] + shr // [(0x029d9... * r) >> 0xc3 - k, y, k, x] + + // Clean stack + swap3 pop pop pop // [result] + + finish jump + + ret_zero: + 0x00 dup1 mstore + 0x20 0x00 return + finish: + // Return stack: [result] +} + +// https://github.com/transmissions11/solmate/blob/v7/src/utils/FixedPointMathLib.sol#L92 +#define macro LN_WAD(fail) = takes (1) returns (1) { + // Input stack: [x] + 0x00 dup2 sgt // [x > 0, x] + iszero // [x <= 0, x] + jumpi // [x] + + // We want to convert x from 10**18 fixed point to 2**96 fixed point. + // We do this by multiplying by 2**96 / 10**18. But since + // ln(x * C) = ln(x) + ln(C), we can simply do nothing here + // and add ln(2**96 / 10**18) at the end. + + // Reduce range of x to (1, 2) * 2**96 + // ln(2^k * x) = k * ln(2) + ln(x) + 0x60 // [0x60, x] + dup2 LOG_2(fail) // [log2(x), 0x60, x] + sub // [k, x] + + dup2 dup2 // [k, x, k, x] + 0x9f sub // [0x9f - k, x, k, x] + shl // [x << (0x9f - k), k, x] + 0x9f shr // [x_new, k, x] + swap2 pop // [k, x] + + // Evaluate using a (8, 8)-term rational approximation. + // p is made monic, we will multiply by a scale factor later. + dup2 // [x, k, x] + 0x29508e458543d8aa4df2abee78 + add // [p, k, x] + + dup3 mul // [p * x, k, x] + 0x60 sar // [(p * x) >> 0x60, k, x] + 0x0139601a2efabe717e604cbb4894 + add // [p, k, x] + + dup3 mul // [p * x, k, x] + 0x60 sar // [(p * x) >> 0x60, k, x] + 0x02247f7a7b6594320649aa03aba1 + add // [p, k, x] + + 0x8c3f38e95a6b1ff2ab1c3b3437 + swap1 dup4 mul // [p * x, 0x8c3f..., k, x] + 0x60 sar // [(p * x) >> 0x60, 0x8c3f..., k, x] + sub // [p, k, x] + + 0x02384773bdf1ac5676facced6091 + swap1 dup4 mul // [p * x, 0x0238..., k, x] + 0x60 sar // [(p * x) >> 0x60, 0x0238..., k, x] + sub // [p, k, x] + + 0xb9a025d814b29c212b8b1a07ce + swap1 dup4 mul // [p * x, 0xb9a0..., k, x] + 0x60 sar // [(p * x) >> 0x60, 0xb9a0..., k, x] + sub // [p, k, x] + + 0x0a09507084cc699bb0e71ea86a + 0x60 shl // [0x0a09... << 0x60, p, k, x] + swap1 // [p, 0x0a09... << 0x60, k, x] + dup4 mul // [p * x, 0x0a09... << 0x60, k, x] + sub // [p, k, x] + + // We leave p in 2**192 basis so we don't need to scale it back up for the division. + // q is monic by convention. + dup3 // [x, p, k, x] + 0x465772b2bbbb5f824b15207a30 + add // [q, p, k, x] + + dup4 mul // [q * x, p, k, x] + 0x60 sar // [(q * x) >> 0x60, p, k, x] + 0x0388eaa27412d5aca026815d636e + add // [q, p, k, x] + + dup4 mul // [q * x, p, k, x] + 0x60 sar // [(q * x) >> 0x60, p, k, x] + 0x0df99ac502031bf953eff472fdcc + add // [q, p, k, x] + + dup4 mul // [q * x, p, k, x] + 0x60 sar // [(q * x) >> 0x60, p, k, x] + 0x13cdffb29d51d99322bdff5f2211 + add // [q, p, k, x] + + dup4 mul // [q * x, p, k, x] + 0x60 shr // [(q * x) >> 0x60, p, k, x] + 0x0a0f742023def783a307a986912e + add // [q, p, k, x] + + dup4 mul // [q * x, p, k, x] + 0x60 sar // [(q * x) >> 0x60, p, k, x] + 0x01920d8043ca89b5239253284e42 + add // [q, p, k, x] + + dup4 mul // [q * x, p, k, x] + 0x60 sar // [(q * x) >> 0x60, p, k, x] + 0x0b7a86d7375468fac667a0a527 + add // [q, p, k, x] + + // The q polynomial is known not to have zeros in the domain. + // No scaling required because p is already 2**96 too large. + swap1 sdiv // [p / q (r), k, x] + + // r is in the range (0, 0.125) * 2**96 + + // Finalization, we need to: + // * multiply by the scale factor s = 5.549... + // * add ln(2**96 / 10**18) + // * add k * ln(2) + // * multiply by 10**18 / 2**96 = 5**18 >> 78 + + // mul s * 5e18 * 2**96, base is now 5**18 * 2**192 + 0x1340daa0d5f769dba1915cef59f0815a5506 mul + + // add ln(2) * k * 5e18 * 2**192 + swap1 // [k, r, x] + 0x0267a36c0c95b3975ab3ee5b203a7614a3f75373f047d803ae7b6687f2b3 + mul // [k * 0x0267..., r, x] + add // [r, x] + + // add ln(2**96 / 10**18) * 5e18 * 2**192 + 0x57115e47018c7177eebf7cd370a3356a1b7863008a5ae8028c72b8864284 + add // [r, x] + + // base conversion: mul 2**18 / 2**192 + 0xAE sar // [r >> 0xAE, x] + + finish jump + + finish: + // Clean stack + swap1 pop + // Return stack: [result] +} + +// https://github.com/transmissions11/solmate/blob/v7/src/utils/FixedPointMathLib.sol#L29 +#define macro POW_WAD(fail) = takes (2) returns (1) { + // Input Stack: [x, y] + LN_WAD(fail) // [lnWad(x), y] + mul // [lnWad(x) * y] + [WAD] swap1 // [lnWad(x) * y, 1e18] + sdiv // [(lnWad(x) * y) / 1e18] + EXP_WAD(fail) // [result] +} + +//////////////////////////////////////////////////////////////// +// LOW LEVEL FIXED POINT OPERATIONS // +//////////////////////////////////////////////////////////////// + +// https://github.com/transmissions11/solmate/blob/main/src/utils/FixedPointMathLib.sol#L34 +#define macro MUL_DIV_DOWN(fail) = takes (3) returns (1) { + // Input stack: [x, y, denominator] + dup1 dup3 mul // [x * y, x, y, denominator] + dup1 // [x * y, x * y, x, y, denominator] + swap2 dup1 // [x, x, x * y, x * y, y, denominator] + + iszero // [x == 0, x, x * y, x * y, y, denominator] + swap2 // [x * y, x, x == 0, x * y, y, denominator] + div // [(x * y) / x, x == 0, x * y, y, denominator] + dup4 eq // [y == (x * y) / x, x == 0, x * y, y, denominator] + or // [y == (x * y) / x | x == 0, x * y, y, denominator] + swap2 pop // [x * y, y == (x * y) / x | x == 0, denominator] + swap1 dup3 // [denominator, y == (x * y) / x | x == 0, x * y, denominator] + iszero iszero // [denominator != 0, y == (x * y) / x | x == 0, x * y, denominator] + and // [denominator != 0 & y == (x * y) / x | x == 0, x * y, denominator] + + iszero jumpi // [x * y, denominator] + + div // [(x * y) / denominator] + // Return stack: [(x * y) / denominator] +} + +// https://github.com/transmissions11/solmate/blob/main/src/utils/FixedPointMathLib.sol#L53 +#define macro MUL_DIV_UP(fail) = takes (3) returns (1) { + // Input stack: [x, y, denominator] + dup1 dup3 mul // [x * y, x, y, denominator] + dup1 // [x * y, x * y, x, y, denominator] + swap2 dup1 // [x, x, x * y, x * y, y, denominator] + + iszero // [x == 0, x, x * y, x * y, y, denominator] + swap2 // [x * y, x, x == 0, x * y, y, denominator] + div // [(x * y) / x, x == 0, x * y, y, denominator] + dup4 eq // [y == (x * y) / x, x == 0, x * y, y, denominator] + or // [y == (x * y) / x | x == 0, x * y, y, denominator] + swap2 pop // [x * y, y == (x * y) / x | x == 0, denominator] + swap1 dup3 // [denominator, y == (x * y) / x | x == 0, x * y, denominator] + iszero iszero // [denominator != 0, y == (x * y) / x | x == 0, x * y, denominator] + and // [denominator != 0 & y == (x * y) / x | x == 0, x * y, denominator] + + iszero jumpi // [x * y, denominator] + + dup1 // [x * y, x * y, denominator] + iszero iszero // [x * y != 0, x * y, denominator] + + dup3 // [denominator, x * y != 0, x * y, denominator] + 0x01 // [1, denominator, x * y != 0, x * y, denominator] + dup4 // [x * y, 1, denominator, x * y != 0, x * y, denominator] + sub // [x * y - 1, denominator, x * y != 0, x * y, denominator] + div // [x * y - 1 / denominator, x * y != 0, x * y, denominator] + 0x01 // [1, x * y - 1 / denominator, x * y != 0, x * y, denominator] + add // [(x * y - 1 / denominator) + 1, x * y != 0, x * y, denominator] + + mul // [((x * y - 1 / denominator) + 1) * (x * y != 0), x * y, denominator] + + // Clear extra stack items before continuing + swap2 // [denominator, x * y, ((x * y - 1 / denominator) + 1) * (x * y != 0)] + pop pop // [((x * y - 1 / denominator) + 1) * (x * y != 0)] + // Return stack: [((x * y - 1 / denominator) + 1) * (x * y != 0)] +} + +// https://github.com/transmissions11/solmate/blob/main/src/utils/FixedPointMathLib.sol#L74 +// TODO: Optimize, works but not great +#define macro RPOW(fail) = takes (3) returns (1) { + // Input stack: [x, n, scalar] + dup1 // [x, x, n, scalar] + default jumpi // Jump to "default" if x != 0 + + // TODO: Fix hack- code following `finish` label pops four items off of + // the stack, so we fill it with extra items here in order to return + // the scalar or 0. + + dup3 dup4 // [scalar, scalar, x, n, scalar] + dup4 iszero // [n == 0, scalar, scalar, x, n, scalar] + finish jumpi // If n == 0 && x == 0, return the scalar (0 ** 0 = 1). + + // 0 ** n = 0 + 0x00 dup1 finish jump // Finish execution + + default: + dup3 // [scalar, x, n, scalar] + 0x01 shr // [scalar >> 1, x, n, scalar] + + dup4 // [result, scalar >> 1, x, n, scalar] + 0x02 // [2, result, scalar >> 1, x, n, scalar] + dup5 // [n, 2, result, scalar >> 1, x, n, scalar] + mod // [n % 2, result, scalar >> 1, x, n, scalar] + + // Set result to scalar for now if n % 2 is even + iszero loop jumpi // [result, scalar >> 1, x, n, scalar]] + + // Set result to x for now if n % 2 is odd + pop dup2 // [result, scalar >> 1, x, n, scalar] + loop: + dup4 // [n, result, scalar >> 1, x, n, scalar] + iszero finish jumpi // If n == 0, the loop is finished. + + // Divide n by 2 + dup4 // [n, result, scalar >> 1, x, n, scalar] + 0x01 shr // [n >> 1, result, scalar >> 1, x, n, scalar] + swap4 pop // [result, scalar >> 1, x, n, scalar] + + // Revert if x ** 2 will overflow. + dup3 // [x, result, scalar >> 1, x, n, scalar] + 0x80 shr // [x >> 128, result, scalar >> 1, x, n, scalar] + + // Square x and duplicate it on the stack for use later. + dup4 // [x, x >> 128, result, scalar >> 1, x, n, scalar] + dup1 mul // [x * x, x >> 128, result, scalar >> 1, x, n, scalar] + dup1 // [x * x, x * x, x >> 128, result, scalar >> 1, x, n, scalar] + + // Add x ** 2 to scalar >> 1 + dup5 // [scalar >> 1, x * x, x * x, x >> 128, result, scalar >> 1, x, n, scalar] + add // [(scalar >> 1) + (x * x), x * x, x >> 128, result, scalar >> 1, x, n, scalar] + + // Revert if x ** 2 + scalar >> 1 overflowed + swap2 // [x >> 128, x * x, (scalar >> 1) + (x * x), result, scalar >> 1, x, n, scalar] + swap1 // [x * x, x >> 128, (scalar >> 1) + (x * x), result, scalar >> 1, x, n, scalar] + dup3 lt // [(scalar >> 1) + (x * x) < x * x, x >> 128, (scalar >> 1) + (x * x), result, scalar >> 1, x, n, scalar] + or jumpi // [(scalar >> 1) + (x * x), result, scalar >> 1, x, n, scalar] + + // Set x to ((scalar >> 1) + (x * x)) / scalar + dup6 // [scalar, (scalar >> 1) + (x * x), result, scalar >> 1, x, n, scalar] + swap1 // [(scalar >> 1) + (x * x), scalar, result, scalar >> 1, x, n, scalar] + div // [((scalar >> 1) + (x * x)) / scalar, result, scalar >> 1, x, n, scalar] + swap3 pop // [result, scalar >> 1, x, n, scalar] + + 0x02 // [2, result, scalar >> 1, x, n, scalar] + dup5 // [n, 2, result, scalar >> 1, x, n, scalar] + mod // [n % 2, result, scalar >> 1, x, n, scalar] + + // If n is even, continue loop + iszero loop jumpi + // If n is odd, continue logic + + // Multiply x * result + dup1 // [result, result, scalar >> 1, x, n, scalar] + dup4 // [x, result, result, scalar >> 1, x, n, scalar] + mul // [x * result, result, scalar >> 1, x, n, scalar] + dup1 // [x * result, x * result, result, scalar >> 1, x, n, scalar] + dup1 // [x * result, x * result, x * result, result, scalar >> 1, x, n, scalar] + + // Check if x * result overflowed + dup6 // [x, x * result, x * result, x * result, result, scalar >> 1, x, n, scalar] + swap1 // [x * result, x, x * result, x * result, result, scalar >> 1, x, n, scalar] + div // [x * result / x, x * result, x * result, result, scalar >> 1, x, n, scalar] + dup4 // [result, x * result / x, x * result, x * result, result, scalar >> 1, x, n, scalar] + eq iszero // [result != (x * result / x), x * result, x * result, result, scalar >> 1, x, n, scalar] + dup6 // [x, result != (x * result / x), x * result, x * result, result, scalar >> 1, x, n, scalar] + iszero iszero // [x != 0, result != (x * result / x), x * result, x * result, result, scalar >> 1, x, n, scalar] + and // [x != 0 & result != (x * result / x), x * result, x * result, result, scalar >> 1, x, n, scalar] + swap2 // [x * result, x * result, x != 0 & result != (x * result / x), result, scalar >> 1, x, n, scalar] + + // Round to the nearest number + dup5 // [scalar >> 1, x * result, x * result, x != 0 & result != (x * result / x), result, scalar >> 1, x, n, scalar] + add // [(scalar >> 1) + (x * result), x * result, x != 0 & result != (x * result / x), result, scalar >> 1, x, n, scalar] + + // Check if x ** 2 + scalar >> 1 overflowed + swap2 // [x != 0 & result != (x * result / x), x * result, (scalar >> 1) + (x * result), result, scalar >> 1, x, n, scalar] + swap1 // [x * result, x != 0 & result != (x * result / x), (scalar >> 1) + (x * result), result, scalar >> 1, x, n, scalar] + dup3 lt // [(scalar >> 1) + (x * result) < x * result, x != 0 & result != (x * result / x), (scalar >> 1) + (x * result), result, scalar >> 1, x, n, scalar] + + // Revert if ((scalar >> 1) + (x * result)) < x * result OR x != 0 & result != (x * result / x) + or jumpi // [(scalar >> 1) + (x * result), result, scalar >> 1, x, n, scalar] + + // Scale rounded result + dup6 // [scalar, (scalar >> 1) + (x * result), result, scalar >> 1, x, n, scalar] + swap1 // [(scalar >> 1) + (x * result), scalar, result, scalar >> 1, x, n, scalar] + div // [(scalar >> 1) + (x * result)) / scalar, result, scalar >> 1, x, n, scalar] + swap1 pop // [result, scalar >> 1, x, n, scalar] + + loop jump // Continue loop + // Return result + finish: + // Clean Stack + swap4 // [scalar, scalar >> 1, x, n, result] + pop pop pop pop // [result] + // Return stack: [result] +} + +//////////////////////////////////////////////////////////////// +// GENERAL NUMBER UTILITIES // +//////////////////////////////////////////////////////////////// + +// https://github.com/transmissions11/solmate/blob/v7/src/utils/FixedPointMathLib.sol#L288 +#define macro SQRT() = takes (1) returns (1) { + // Input stack: [x] + + // We start y at x, which will help us make our initial estimate. + dup1 // [y, x] + + // The "correct" value is 1, but this saves a multiplication later. + 0xb5 // [0xb5, y, x] + + 0x10000000000000000000000000000000000 + dup3 // [y, 0x1000..., z, y, x] + lt // [y < 0x1000..., z, y, x] + continue_1 jumpi // [z, y, x] + + 0x40 shl // [z << 0x40, y, x] + swap1 // [y, z << 0x40, x] + 0x80 shr // [y >> 0x80, z << 0x40, x] + swap1 // [z << 0x40, y >> 0x80, x] + + continue_1: + + 0x1000000000000000000 + dup3 // [y, 0x1000..., z, y, x] + lt // [y < 0x1000..., z, y, x] + continue_2 jumpi // [z, y, x] + + 0x20 shl // [z << 0x20, y, x] + swap1 // [y, z << 0x20, x] + 0x40 shr // [y >> 0x40, z << 0x20, x] + swap1 // [z << 0x20, y >> 0x40, x] + + continue_2: + + 0x10000000000 + dup3 // [y, 0x1000..., z, y, x] + lt // [y < 0x1000..., z, y, x] + continue_3 jumpi // [z, y, x] + + 0x10 shl // [z << 0x10, y, x] + swap1 // [y, z << 0x10, x] + 0x20 shr // [y >> 0x20, z << 0x10, x] + swap1 // [z << 0x10, y >> 0x20, x] + + continue_3: + + 0x1000000 + dup3 // [y, 0x1000..., z, y, x] + lt // [y < 0x1000..., z, y, x] + continue_4 jumpi // [z, y, x] + + 0x08 shl // [z << 0x08, y, x] + swap1 // [y, z << 0x08, x] + 0x10 shr // [y >> 0x10, z << 0x08, x] + swap1 // [z << 0x08, y >> 0x10, x] + + continue_4: + + // Goal was to get z*z*y within a small factor of x. More iterations could + // get y in a tighter range. Currently, we will have y in [256, 256*2^16). + // We ensured y >= 256 so that the relative difference between y and y+1 is small. + // That's not possible if x < 256 but we can just verify those cases exhaustively. + + // Now, z*z*y <= x < z*z*(y+1), and y <= 2^(16+8), and either y >= 256, or x < 256. + // Correctness can be checked exhaustively for x < 256, so we assume y >= 256. + // Then z*sqrt(y) is within sqrt(257)/sqrt(256) of sqrt(x), or about 20bps. + + // For s in the range [1/256, 256], the estimate f(s) = (181/1024) * (s+1) is in the range + // (1/2.84 * sqrt(s), 2.84 * sqrt(s)), with largest error when s = 1 and when s = 256 or 1/256. + + // Since y is in [256, 256*2^16), let a = y/65536, so that a is in [1/256, 256). Then we can estimate + // sqrt(y) using sqrt(65536) * 181/1024 * (a + 1) = 181/4 * (y + 65536)/65536 = 181 * (y + 65536)/2^18. + + // There is no overflow risk here since y < 2^136 after the first branch above. + + // A mul is saved from starting z at 181. + swap1 // [y, z, x] + 0x010000 add // [y + 0x010000, z, x] + mul // [(y + 0x010000) * z, x] + 0x12 shr // [((y + 0x010000) * z) >> 0x12, x] + + // Given the worst case multiplicative error of 2.84 above, 7 iterations should be enough. + dup1 dup3 // [x, z, z, x] + div // [x / z, z, x] + add // [x / z + z, x] + 0x01 shr // [(x / z + z) >> 0x01, x] + + dup1 dup3 // [x, z, z, x] + div // [x / z, z, x] + add // [x / z + z, x] + 0x01 shr // [(x / z + z) >> 0x01, x] + + dup1 dup3 // [x, z, z, x] + div // [x / z, z, x] + add // [x / z + z, x] + 0x01 shr // [(x / z + z) >> 0x01, x] + + dup1 dup3 // [x, z, z, x] + div // [x / z, z, x] + add // [x / z + z, x] + 0x01 shr // [(x / z + z) >> 0x01, x] + + dup1 dup3 // [x, z, z, x] + div // [x / z, z, x] + add // [x / z + z, x] + 0x01 shr // [(x / z + z) >> 0x01, x] + + dup1 dup3 // [x, z, z, x] + div // [x / z, z, x] + add // [x / z + z, x] + 0x01 shr // [(x / z + z) >> 0x01, x] + + dup1 dup3 // [x, z, z, x] + div // [x / z, z, x] + add // [x / z + z, x] + 0x01 shr // [(x / z + z) >> 0x01, x] + + // If x+1 is a perfect square, the Babylonian method cycles between + // floor(sqrt(x)) and ceil(sqrt(x)). This statement ensures we return floor. + // See: https://en.wikipedia.org/wiki/Integer_square_root#Using_only_integer_division + // Since the ceil is rare, we save gas on the assignment and repeat division in the rare case. + // If you don't care whether the floor or ceil square root is returned, you can remove this statement. + dup1 dup1 swap3 // [x, z, z, z] + div // [x / z, z, z] + lt // [(x / z) < z, z] + swap1 sub // [z - (x / z) < z] +} + +// https://github.com/transmissions11/solmate/blob/v7/src/utils/FixedPointMathLib.sol#L352 +#define macro LOG_2(fail) = takes (1) returns (1) { + // Input stack: [x] + + dup1 iszero // [x == 0, x] + jumpi // [x] + + dup1 // [x, x] + 0xffffffffffffffffffffffffffffffff + lt // [0xffff... < x, x] + 0x07 shl // [r, x] + + dup2 dup2 // [r, x, r, x] + shr // [x >> r, r, x] + 0xffffffffffffffff lt // [0xffff... < (x >> r), r, x] + 0x06 shl // [(0xffff... < (x >> r)) << 6, r, x] + or // [r | (0xffff... < (x >> r)) << 6, x] + + dup2 dup2 // [r, x, r, x] + shr // [x >> r, r, x] + 0xffffffff lt // [0xffff... < (x >> r), r, x] + 0x05 shl // [(0xffff... < (x >> r)) << 5, r, x] + or // [r | (0xffff... < (x >> r)) << 5, x] + + dup2 dup2 // [r, x, r, x] + shr // [x >> r, r, x] + 0xffff lt // [0xffff < (x >> r), r, x] + 0x04 shl // [(0xffff < (x >> r)) << 4, r, x] + or // [r | (0xffff < (x >> r)) << 4, x] + + dup2 dup2 // [r, x, r, x] + shr // [x >> r, r, x] + 0xff lt // [0xff < (x >> r), r, x] + 0x03 shl // [(0xff < (x >> r)) << 3, r, x] + or // [r | (0xff < (x >> r)) << 3, x] + + dup2 dup2 // [r, x, r, x] + shr // [x >> r, r, x] + 0x0f lt // [0x0f < (x >> r), r, x] + 0x02 shl // [(0x0f < (x >> r)) << 2, r, x] + or // [r | (0x0f < (x >> r)) << 2, x] + + dup2 dup2 // [r, x, r, x] + shr // [x >> r, r, x] + 0x03 lt // [0x03 < (x >> r), r, x] + 0x01 shl // [(0x03 < (x >> r)) << 1, r, x] + or // [r | (0x03 < (x >> r)) << 1, x] + + dup2 dup2 // [r, x, r, x] + shr // [x >> r, r, x] + 0x01 lt // [0x01 < (x >> r), r, x] + or // [r, x] + swap1 pop // [r] + + // Return stack: // [result] +} + +/// @notice Calculates the cube root of the stack input +/// Credits: https://github.com/Vectorized/solady/blob/main/src/utils/FixedPointMathLib.sol#L504 +#define macro CBRT() = takes (1) returns (1) { + // Input Stack: [x] + + // r construction + + dup1 // [x, x] + 0xffffffffffffffffffffffffffffffff // [0xffffffffffffffffffffffffffffffff, x, x] + lt // [0xffffffffffffffffffffffffffffffff< x, x] + 0x7 shl // [0xffffffffffffffffffffffffffffffff < x << 7, x] + // r = 0xffffffffffffffffffffffffffffffff < x << 7 + + dup2 dup2 // [r, x, r, x] + shr // [x >> r, r, x] + 0xffffffffffffffff // [0xffffffffffffffff, x >> r, r, x] + lt // [0xffffffffffffffff < x >> r, r, x] + 0x6 shl // [0xffffffffffffffff < x >> r << 6, r, x] + or // [0xffffffffffffffff < x >> r << 6 | r, x] + // r' = r | (0xffffffffffffffff < (x >> r)) << 6 + + dup2 dup2 // [r', x, r', x] + shr // [x >> r', r', x] + 0xffffffff // [0xffffffff, x >> r', r', x] + lt // [0xffffffff < x >> r, r', x] + 0x5 shl // [0xffffffff < x >> r << 5, r', x] + or // [0xffffffff < x >> r << 5 | r', x] + // r' = r' | 0xffffffff < x >> r << 5 + + dup2 dup2 // [r', x, r', x] + shr // [x >> r', r', x] + 0xffff // [0xffff, x >> r', r',x] + lt // [0xffff < x >> r', r', x] + 0x4 shl // [0xffff < x >> r' << 4, r', x] + or // [0xffff < x >> r' << 4 | r', x] + // r' = r' | 0xffff < x >> r' << 4 + + dup2 dup2 // [r', x, r', x] + shr // [x >> r', r', x] + 0xff // [0xff, x >> r', r', x] + lt // [0xff < x >> r', r', x] + 0x3 shl // [0xff < x >> r' << 3, r', x] + or // [0xff < x >> r' << 3 | r', x] + // r' = r'|0xff < x >> r' << 3 + + // z construction + + 0xff // [0xff, r', x] + dup3 dup3 // [r', x, 0xff, r', x] + shr // [x >> r', 0xff, r', x] + 0xf // [0xf, x >> r', 0xff, r', x] + lt // [0xf < x >> r', 0xff, r', x] + 0x3 // [3, 0xf < x >> r', 0xff, r', x] + dup4 // [r', 3, 0xf < x >> r', 0xff, r', x] + div // [r' / 3, 0xf < x >> r', 0xff, r', x] + add // [r' / 3 + 0xf < x >> r', 0xff, r', x] + shl // [0xff << r' / 3 + 0xf < x >> r', r', x] + // z = 0xff << r' / 3 + 0xf < x >> r' + + 0x3 // [0x3, z, r', x] + swap1 // [z, 0x3, r', x] + swap2 // [r', 0x3, z, x] + mod // [r' % 3, z, x] + 0x7f624b // [0x7f624b, r' % 3, z, x] + 0xe8 // [0xe8, 0x7f624b, r' % 3, z, x] + shl // [0x7f624b << 0xe8, r' % 3, z, x] + swap1 // [r' % 3, 0x7f624b << 0xe8, z, x] + byte // [byte(r' % 3, 0x7f624b << 0xe8), z, x] + swap1 // [z, byte(r' % 3, 0x7f624b << 0xe8), x] + div // [z / byte(r' % 3, 0x7f624b << 0xe8), x] + // z' = z / byte(r' % 3, 0xe8 << 0x7f624b) + + // Round 1 / 7 + 0x3 // [3, z', x] + swap1 dup1 // [z', z', 3, x] + dup1 dup1 // [z', z', z', z', 3, x] + mul // [z' * z', z', z', 3, x] + dup5 // [x, z' * z', z', z', 3, x] + div add // [x / z' * z' + z', z', 3, x] + add div // [((x / (z' * z')) + z') + z') / 3, x] + // z' = ((x / (z' * z'))+ z') + z') / 3 + + // Round 2 / 7 + 0x3 // [3, z', x] + swap1 dup1 // [z', z', 3, x] + dup1 dup1 // [z', z', z', z', 3, x] + mul // [z' * z', z', z', 3, x] + dup5 // [x, z' * z', z', z', 3, x] + div add // [x / z' * z' + z', z', 3, x] + add div // [((x / (z' * z'))+ z') + z') / 3, x] + // z' = ((x / (z' * z'))+ z') + z') / 3 + + // Round 3 / 7 + 0x3 // [3, z', x] + swap1 dup1 // [z', z', 3, x] + dup1 dup1 // [z', z', z', z', 3, x] + mul // [z' * z', z', z', 3, x] + dup5 // [x, z' * z', z', z', 3, x] + div add // [x / z' * z' + z', z', 3, x] + add div // [((x / (z' * z'))+ z') + z') / 3, x] + // z' = ((x / (z' * z'))+ z') + z') / 3 + + // Round 4 / 7 + 0x3 // [3, z', x] + swap1 dup1 // [z', z', 3, x] + dup1 dup1 // [z', z', z', z', 3, x] + mul // [z' * z', z', z', 3, x] + dup5 // [x, z' * z', z', z', 3, x] + div add // [x / z' * z' + z', z', 3, x] + add div // [((x / (z' * z'))+ z') + z') / 3, x] + // z' = ((x / (z' * z'))+ z') + z') / 3 + + // Round 5 / 7 + 0x3 // [3, z', x] + swap1 dup1 // [z', z', 3, x] + dup1 dup1 // [z', z', z', z', 3, x] + mul // [z' * z', z', z', 3, x] + dup5 // [x, z' * z', z', z', 3, x] + div add // [x / z' * z' + z', z', 3, x] + add div // [((x / (z' * z'))+ z') + z') / 3, x] + // z' = ((x / (z' * z'))+ z') + z') / 3 + + // Round 6 / 7 + 0x3 // [3, z', x] + swap1 dup1 // [z', z', 3, x] + dup1 dup1 // [z', z', z', z', 3, x] + mul // [z' * z', z', z', 3, x] + dup5 // [x, z' * z', z', z', 3, x] + div add // [x / z' * z' + z', z', 3, x] + add div // [((x / (z' * z'))+ z') + z') / 3, x] + // z' = ((x / (z' * z'))+ z') + z') / 3 + + // Round 7 / 7 + 0x3 // [3, z', x] + swap1 dup1 // [z', z', 3, x] + dup1 dup1 // [z', z', z', z', 3, x] + mul // [z' * z', z', z', 3, x] + dup5 // [x, z' * z', z', z', 3, x] + div add // [x / z' * z' + z', z', 3, x] + add div // [((x / (z' * z'))+ z') + z') / 3, x] + // z' = ((x / (z' * z'))+ z') + z') / 3 + + // Final operation + dup1 swap2 // [x, z', z'] + dup2 dup1 // [z', z', x, z', z'] + mul // [z' * z', x, z', z'] + swap1 // [x, z' * z', z', z'] + div // [x / (z' * z'), z', z'] + lt // [x / (z' * z') < z', z'] + swap1 sub // [z' - (x / (z' * z') < z')] + + // Return stack: [result: z'] +} + +//////////////////////////////////////////////////////////////// +// HELPER MACROS // +//////////////////////////////////////////////////////////////// + +#define macro ARRANGE_STACK_MULWAD() = takes (3) returns (3) { + // Input stack: [WAD, x, y] + swap2 // [y, x, WAD] + swap1 // [x, y, WAD] +} + +#define macro ARRANGE_STACK_DIVWAD() = takes (3) returns (3) { + // Input stack: [WAD, x, y] + swap1 // [x, WAD, y] +} + +// TESTS + +#define macro TEST_ASSERT_EQ() = { + eq continue jumpi + 0x00 dup1 revert + continue: +} + +// test wad mul for positive numbers +#define test TEST_WAD_DIV() = { + 0xDE0B6B3A7640000 // [y (1e18)] + 0x1BC16D674EC80000 // [x (2e18),y] + WAD_MUL(fail) // result + 0x1BC16D674EC80000 + TEST_ASSERT_EQ() + continue jump + + fail: + FAIL() + continue: +} + +// test wad mul for positive numbers +#define test TEST_WAD_MUL() = { + 0x0DE0B6B3A7640000 // [y (1e18)] + 0x1BC16D674EC80000 // [x (2e18), y] + WAD_MUL(fail) // result + + 0x1BC16D674EC80000 + TEST_ASSERT_EQ() + continue jump + // catch jump label + fail: + 0x00 dup1 revert + continue: +} + +#define test FAIL_WAD_MUL() = { + 0xF0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + 0x20 + WAD_MUL(fail) + 0x00 dup1 revert + + // succeed if fails + fail: +} + +#define test FAIL_WAD_DIV() = { + 0x00 + 0x0DE0B6B3A7640000 + WAD_DIV(fail) + 0x00 dup1 revert + + // succeed if fails + fail: +} + + +#define test TEST_TO_WAD_UNSAFE() = { + // Test 0x2 * WAD = 2e18 + 0x02 + TO_WAD_UNSAFE() + 0x1BC16D674EC80000 // [2*e18] + TEST_ASSERT_EQ() +} diff --git a/src/math/__TEMP__ohdnimzopkbndglbmvjbzlrpyrrzphnrTrigonometry.huff b/src/math/__TEMP__ohdnimzopkbndglbmvjbzlrpyrrzphnrTrigonometry.huff new file mode 100644 index 00000000..a74aa9a7 --- /dev/null +++ b/src/math/__TEMP__ohdnimzopkbndglbmvjbzlrpyrrzphnrTrigonometry.huff @@ -0,0 +1,218 @@ +#define function sin(uint256) pure returns (int256) +#define function cos(uint256) pure returns (int256) + +#define macro SIN_WRAPPER() = takes (0) returns (0) { + 0x04 calldataload // [angle] + SIN() // [sin(angle)] + 0x00 mstore // [] + 0x20 0x00 return +} + +#define macro COS_WRAPPER() = takes (0) returns (0) { + 0x04 calldataload // [angle] + COS() // [cos(angle)] + 0x00 mstore // [] + 0x20 0x00 return +} + +#define macro MAIN() = takes (0) returns (0) { + pc calldataload 0xE0 shr + dup1 __FUNC_SIG(sin) eq sin jumpi + dup1 __FUNC_SIG(cos) eq cos jumpi + + 0x00 dup1 revert + + sin: + SIN_WRAPPER() + cos: + COS_WRAPPER() +} + +/// @title Trigonometry +/// @notice SPDX-License-Identifier: MIT +/// @author mds1 +/// @author clabby +/// @notice Basic trigonometry functions where inputs and outputs are integers. +/// Inputs are specified in radians scaled by 1e18, and similarly outputs are scaled by 1e18. +/// @notice Adapted from mds1 (https://github.com/mds1/solidity-trigonometry/blob/main/src/Trigonometry.sol) + +//////////////////////////////////////////////////////////////// +// CONSTANTS // +//////////////////////////////////////////////////////////////// + +// Table index into the trigonometric table +#define constant INDEX_WIDTH = 0x08 + +// Interpolation between successive entries in the table +#define constant INTERP_WIDTH = 0x10 +#define constant INDEX_OFFSET = 0x14 +#define constant INTERP_OFFSET = 0x04 +#define constant ANGLES_IN_CYCLE = 0x40000000 +#define constant QUADRANT_HIGH_MASK = 0x20000000 +#define constant QUADRANT_LOW_MASK = 0x10000000 +#define constant SINE_TABLE_SIZE = 0x100 + +// Pi as an 18 decimal value, which is plenty of accuracy: "For JPL's highest accuracy calculations, which are for +// interplanetary navigation, we use 3.141592653589793: https://www.jpl.nasa.gov/edu/news/2016/3/16/how-many-decimals-of-pi-do-we-really-need/ +#define constant PI = 0x2B992DDFA23249D6 +#define constant TWO_PI = 0x57325BBF446493AC +#define constant PI_OVER_TWO = 0x15CC96EFD1192500 + +// The constant sine lookup table was generated by generate_trigonometry.py. We must use a constant +// bytes array because constant arrays are not supported in Solidity. Each entry in the lookup +// table is 4 bytes. Since we're using 32-bit parameters for the lookup table, we get a table size +// of 2^(32/4) + 1 = 257, where the first and last entries are equivalent (hence the table size of +// 256 defined above) +#define constant ENTRY_BYTES = 0x04 // each entry in the lookup table is 4 bytes +#define constant ENTRY_MASK = 0xFFFFFFFF // mask used to cast bytes32 -> lookup table entry +#define table SIN_LUT { + 0x00000000000000000000000000000000000000000000000000000000000001000000000000c90f8801921d20025b26d703242abf03ed26e604b6195d057f00350647d97c0710a34507d95b9e08a2009a096a90490a3308bc0afb68050bc3ac350c8bd35e0d53db920e1bc2e40ee387660fab272b1072a0481139f0cf120116d512c8106e138edbb1145576b1151bdf8515e2144416a81305176dd9de183366e818f8b83c19bdcbf31a82a0251b4732ef1c0b826a1ccf8cb31d934fe51e56ca1e1f19f97b1fdcdc1b209f701c2161b39f2223a4c522e541af23a6887e2467775725280c5d25e845b626a8218527679df42826b92828e5714a29a3c4852a61b1012b1f34eb2bdc4e6f2c98fbba2d553afb2e110a622ecc681e2f8752623041c76030fbc54d31b54a5d326e54c73326e2c233def2873496824f354d905636041ad936ba2013376f9e46382493b038d8fe93398cdd323a402dd13af2eeb73ba51e293c56ba703d07c1d53db832a53e680b2c3f1749b73fc5ec974073f21d4121589a41ce1e64427a41d04325c13543d09aec447acd50452456bc45cd358f46756827471cece647c3c22e4869e664490f57ee49b415334a581c9d4afb6c974b9e038f4c3fdff34ce100344d8162c34e2106174ebfe8a44f5e08e24ffb654c5097fc5e5133cc9451ced46e5269126e53028517539b2aef5433027d54ca0a4a556040e255f5a4d2568a34a9571deef957b0d2555842dd5458d40e8c5964649759f3de125a8279995b1035ce5b9d11535c290acc5cb420df5d3e52365dc79d7b5e50015d5ed77c895f5e0db25fe3b38d60686cce60ec382f616f146b61f1003e6271fa6862f201ac637114cc63ef328f646c59bf64e889256563bf9165ddfbd266573cbb66cf811f6746c7d767bd0fbc683257aa68a69e806919e31f698c246b69fd614a6a6d98a36adcc9646b4af2786bb812d06c24295f6c8f351b6cf934fb6d6227f96dca0d146e30e3496e96a99c6efb5f116f5f02b16fc1938470231099708378fe70e2cbc571410804719e2cd171fa394872552c8472af05a67307c3cf735f662573b5ebd0740b53fa745f9dd074b2c8837504d3447555bd4b75a585ce75f42c0a7641af3c768e0ea576d9498877235f2c776c4eda77b417df77fab988784033287884841378c7aba17909a92c794a7c11798a23b079c89f6d7a05eeac7a4210d87a7d055a7ab6cba37aef63237b26cb4e7b5d039d7b920b887bc5e28f7bf8882f7c29fbed7c5a3d4f7c894bdd7cb727237ce3ceb17d0f42177d3980eb7d628ac57d8a5f3f7db0fdf77dd6668e7dfa98a77e1d93e97e3f57fe7e5fe4927e7f39567e9d55fb7eba3a387ed5e5c57ef0585f7f0991c37f2191b37f3857f57f4de4507f62368e7f754e7f7f872bf27f97cebc7fa736b37fb563b27fc255957fce0c3d7fd8878d7fe1c76a7fe9cbbf7ff094777ff621817ffa72d07ffd88597fff62157fffffff +} + +#define constant WAD = 0x0de0b6b3a7640000 +#define constant I32_MAX = 0x7fffffff + +//////////////////////////////////////////////////////////////// +// BASIC TRIG // +//////////////////////////////////////////////////////////////// + +/// @notice Return the sine of a value, specified in radians scaled by 1e18 +/// @dev This algorithm for converting sine only uses integer values, and it works by dividing the +/// circle into 30 bit angles, i.e. there are 1,073,741,824 (2^30) angle units, instead of the +/// standard 360 degrees (2pi radians). From there, we get an output in range -2,147,483,647 to +/// 2,147,483,647, (which is the max value of an int32) which is then converted back to the standard +/// range of -1 to 1, again scaled by 1e18 +/// @param _angle Angle to convert +/// @return Result scaled by 1e18 +#define macro SIN() = takes (1) returns (1) { + // Input stack: [angle] + + // Convert angle from from arbitrary radian value (range of 0 to 2pi) to the algorithm's range + // of 0 to 1,073,741,824 + [TWO_PI] dup1 // [TWO_PI, TWO_PI, angle] + swap2 // [angle, TWO_PI, TWO_PI] + mod // [angle % TWO_PI, TWO_PI] + [ANGLES_IN_CYCLE] mul // [ANGLES_IN_CYCLE * (angle % TWO_PI), TWO_PI] + div // [ANGLES_IN_CYCLE * (angle % TWO_PI) / TWO_PI] + // [angle] + + // Apply a mask on an integer to extract a certain number of bits, where angle is the integer + // whose bits we want to get, the width is the width of the bits (in bits) we want to extract, + // and the offset is the offset of the bits (in bits) we want to extract. The result is an + // integer containing _width bits of _value starting at the offset bit + dup1 // [angle, angle] + [INTERP_OFFSET] shr // [angle >> INTERP_OFFSET, angle] + 0x01 dup1 // [0x01, 0x01, angle >> INTERP_OFFSET, angle] + [INTERP_WIDTH] shl // [0x01 << INTERP_WIDTH, 0x01, angle >> INTERP_OFFSET, angle] + sub // [(0x01 << INTERP_WIDTH) - 0x01, angle >> INTERP_OFFSET, angle] + and // [interp, angle] + + dup2 // [angle, interp, angle] + [INDEX_OFFSET] shr // [angle >> INDEX_OFFSET, interp, angle] + 0x01 dup1 // [0x01, 0x01, angle >> INDEX_OFFSET, interp, angle] + [INDEX_WIDTH] shl // [0x01 << INDEX_WIDTH, 0x01, angle >> INDEX_OFFSET, interp, angle] + sub // [(0x01 << INDEX_WIDTH) - 0x01, angle >> INDEX_OFFSET, interp, angle] + and // [index, interp, angle] + + // The lookup table only contains data for one quadrant (since sin is symmetric around both + // axes), so here we figure out which quadrant we're in, then we lookup the values in the + // table then modify values accordingly + dup3 // [angle, index, interp, angle] + [QUADRANT_LOW_MASK] // [QUADRANT_LOW_MASK, angle, index, interp, angle] + and // [QUADRANT_LOW_MASK & angle, index, interp, angle] + iszero // [is_odd_quadrant, index, interp, angle] + + dup4 // [angle, is_odd_quadrant, index, interp, angle] + [QUADRANT_HIGH_MASK] // [QUADRANT_HIGH_MASK, angle, is_odd_quadrant, index, interp, angle] + and // [QUADRANT_HIGH_MASK & angle, is_odd_quadrant, index, interp, angle] + iszero iszero // [is_negative_quadrant, is_odd_quadrant, index, interp, angle] + + // Jump past updating the index if `is_odd_quadrant` is true + dup2 is_odd_q jumpi // [is_negative_quadrant, is_odd_quadrant, index, interp, angle] + + dup3 // [index, is_negative_quadrant, is_odd_quadrant, index, interp, angle] + 0x01 // [0x01, index, is_negative_quadrant, is_odd_quadrant, index, interp, angle] + [SINE_TABLE_SIZE] // [SINE_TABLE_SIZE, 0x01, index, is_negative_quadrant, is_odd_quadrant, index, interp, angle] + sub sub // [SINE_TABLE_SIZE - 0x01 - index, is_negative_quadrant, is_odd_quadrant, index, interp, angle] + swap3 pop // [is_negative_quadrant, is_odd_quadrant, index, interp, angle] + + is_odd_q: + + // We are looking for two consecutive indices in our lookup table + // Since EVM is left aligned, to read n bytes of data from idx i, we must read from `i * data_len` + `n` + // therefore, to read two entries of size entry_bytes `index * entry_bytes` + `entry_bytes * 2` + swap2 // [index, is_odd_quadrant, is_negative_quadrant, interp, angle] + 0x02 add // [index + 0x02, is_odd_quadrant, is_negative_quadrant, interp, angle] + [ENTRY_BYTES] mul // [offset1_2, is_odd_quadrant, is_negative_quadrant, interp, angle] + + // This following snippet will function for any entry_bytes <= 15 + __tablestart(SIN_LUT) // [sin_table_start, offset1_2, is_odd_quadrant, is_negative_quadrant, interp, angle] + add // [sin_table_start + offset1_2, is_odd_quadrant, is_negative_quadrant, interp, angle] + 0x20 swap1 // [sin_table_start + offset1_2, 0x20, is_odd_quadrant, is_negative_quadrant, interp, angle] + 0x00 codecopy // [is_odd_quadrant, is_negative_quadrant, interp, angle] + + 0x00 mload // [x1_2, is_odd_quadrant, is_negative_quadrant, interp, angle] + + // We now read the last two numbers of size entry_bytes from x1_2 + // in example: entry_bytes = 4; x1_2 = 0x00...12345678abcdefgh + // therefore: entry_mask = 0xFFFFFFFF + + // 0x00...12345678abcdefgh >> 8*4 = 0x00...12345678 + // 0x00...12345678 & 0xFFFFFFFF = 0x12345678 + dup1 0x20 shr // [x1_2 >> 0x20, x1_2, is_odd_quadrant, is_negative_quadrant, interp, angle] + [ENTRY_MASK] and // [x1, x1_2, is_odd_quadrant, is_negative_quadrant, interp, angle] + + // 0x00...12345678abcdefgh & 0xFFFFFFFF = 0xabcdefgh + swap1 [ENTRY_MASK] // [ENTRY_MASK, x1_2, x1, is_odd_quadrant, is_negative_quadrant, interp, angle] + and // [x2, x1, is_odd_quadrant, is_negative_quadrant, interp, angle] + + // Approximate angle by interpolating in the table, accounting for the quadrant + dup2 dup2 sub // [x2 - x1, x2, x1, is_odd_quadrant, is_negative_quadrant, interp, angle] + dup6 mul // [interp * (x2 - x1), x2, x1, is_odd_quadrant, is_negative_quadrant, interp, angle] + [INTERP_WIDTH] shr // [(interp * (x2 - x1)) >> INTERP_WIDTH, x2, x1, is_odd_quadrant, is_negative_quadrant, interp, angle] + + swap3 // [is_odd_quadrant, x2, x1, (interp * (x2 - x1)) >> INTERP_WIDTH, is_negative_quadrant, interp, angle] + is_odd jumpi // [x2, x1, (interp * (x2 - x1)) >> INTERP_WIDTH, is_negative_quadrant, interp, angle] + + is_even: + swap1 pop // [x2, (interp * (x2 - x1)) >> INTERP_WIDTH, is_negative_quadrant, interp, angle] + sub // [x2 - (interp * (x2 - x1)) >> INTERP_WIDTH, is_negative_quadrant, interp, angle] + finish jump + is_odd: + pop add // [x1 + (interp * (x2 - x1)) >> INTERP_WIDTH, is_negative_quadrant, interp, angle] + finish: + // Received stack: [sine, is_negative_quadrant, interp, angle] + swap1 // [is_negative_quadrant, sine, interp, angle] + iszero cont jumpi // [sine, interp, angle] + + // Negative 1 + 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + mul // [-sine, interp, angle] + + cont: + // Bring result from the range of -2,147,483,647 through 2,147,483,647 to -1e18 through 1e18. + // This can never overflow because sine is bounded by the above values + [WAD] mul // [1e18 * sine, interp, angle] + [I32_MAX] // [I32_MAX, 1e18 * sine, interp, angle] + swap1 sdiv // [1e18 * sine / I32_MAX, interp, angle] + + // Clean stack: + swap2 pop pop // [1e18 * sine / I32_MAX] + + // Return stack: [1e18 * sine / I32_MAX] +} + +/// @notice Return the cosine of a value, specified in radians scaled by 1e18 +/// @dev This is identical to the sin() method, and just computes the value by delegating to the +/// sin() method using the identity cos(x) = sin(x + pi/2) +/// @dev Overflow when `angle + PI_OVER_TWO > type(uint256).max` is ok, results are still accurate +/// @param _angle Angle to convert +/// @return Result scaled by 1e18 +#define macro COS() = takes (1) returns (1) { + // Input stack: [angle] + + [PI_OVER_TWO] add // [angle + pi/2] + SIN() // [result] + + // Return stack: [result] +} \ No newline at end of file diff --git a/src/math/__TEMP__qakkodxedbspprhymlfrgxlfepgepcrvTrigonometry.huff b/src/math/__TEMP__qakkodxedbspprhymlfrgxlfepgepcrvTrigonometry.huff new file mode 100644 index 00000000..a74aa9a7 --- /dev/null +++ b/src/math/__TEMP__qakkodxedbspprhymlfrgxlfepgepcrvTrigonometry.huff @@ -0,0 +1,218 @@ +#define function sin(uint256) pure returns (int256) +#define function cos(uint256) pure returns (int256) + +#define macro SIN_WRAPPER() = takes (0) returns (0) { + 0x04 calldataload // [angle] + SIN() // [sin(angle)] + 0x00 mstore // [] + 0x20 0x00 return +} + +#define macro COS_WRAPPER() = takes (0) returns (0) { + 0x04 calldataload // [angle] + COS() // [cos(angle)] + 0x00 mstore // [] + 0x20 0x00 return +} + +#define macro MAIN() = takes (0) returns (0) { + pc calldataload 0xE0 shr + dup1 __FUNC_SIG(sin) eq sin jumpi + dup1 __FUNC_SIG(cos) eq cos jumpi + + 0x00 dup1 revert + + sin: + SIN_WRAPPER() + cos: + COS_WRAPPER() +} + +/// @title Trigonometry +/// @notice SPDX-License-Identifier: MIT +/// @author mds1 +/// @author clabby +/// @notice Basic trigonometry functions where inputs and outputs are integers. +/// Inputs are specified in radians scaled by 1e18, and similarly outputs are scaled by 1e18. +/// @notice Adapted from mds1 (https://github.com/mds1/solidity-trigonometry/blob/main/src/Trigonometry.sol) + +//////////////////////////////////////////////////////////////// +// CONSTANTS // +//////////////////////////////////////////////////////////////// + +// Table index into the trigonometric table +#define constant INDEX_WIDTH = 0x08 + +// Interpolation between successive entries in the table +#define constant INTERP_WIDTH = 0x10 +#define constant INDEX_OFFSET = 0x14 +#define constant INTERP_OFFSET = 0x04 +#define constant ANGLES_IN_CYCLE = 0x40000000 +#define constant QUADRANT_HIGH_MASK = 0x20000000 +#define constant QUADRANT_LOW_MASK = 0x10000000 +#define constant SINE_TABLE_SIZE = 0x100 + +// Pi as an 18 decimal value, which is plenty of accuracy: "For JPL's highest accuracy calculations, which are for +// interplanetary navigation, we use 3.141592653589793: https://www.jpl.nasa.gov/edu/news/2016/3/16/how-many-decimals-of-pi-do-we-really-need/ +#define constant PI = 0x2B992DDFA23249D6 +#define constant TWO_PI = 0x57325BBF446493AC +#define constant PI_OVER_TWO = 0x15CC96EFD1192500 + +// The constant sine lookup table was generated by generate_trigonometry.py. We must use a constant +// bytes array because constant arrays are not supported in Solidity. Each entry in the lookup +// table is 4 bytes. Since we're using 32-bit parameters for the lookup table, we get a table size +// of 2^(32/4) + 1 = 257, where the first and last entries are equivalent (hence the table size of +// 256 defined above) +#define constant ENTRY_BYTES = 0x04 // each entry in the lookup table is 4 bytes +#define constant ENTRY_MASK = 0xFFFFFFFF // mask used to cast bytes32 -> lookup table entry +#define table SIN_LUT { + 0x00000000000000000000000000000000000000000000000000000000000001000000000000c90f8801921d20025b26d703242abf03ed26e604b6195d057f00350647d97c0710a34507d95b9e08a2009a096a90490a3308bc0afb68050bc3ac350c8bd35e0d53db920e1bc2e40ee387660fab272b1072a0481139f0cf120116d512c8106e138edbb1145576b1151bdf8515e2144416a81305176dd9de183366e818f8b83c19bdcbf31a82a0251b4732ef1c0b826a1ccf8cb31d934fe51e56ca1e1f19f97b1fdcdc1b209f701c2161b39f2223a4c522e541af23a6887e2467775725280c5d25e845b626a8218527679df42826b92828e5714a29a3c4852a61b1012b1f34eb2bdc4e6f2c98fbba2d553afb2e110a622ecc681e2f8752623041c76030fbc54d31b54a5d326e54c73326e2c233def2873496824f354d905636041ad936ba2013376f9e46382493b038d8fe93398cdd323a402dd13af2eeb73ba51e293c56ba703d07c1d53db832a53e680b2c3f1749b73fc5ec974073f21d4121589a41ce1e64427a41d04325c13543d09aec447acd50452456bc45cd358f46756827471cece647c3c22e4869e664490f57ee49b415334a581c9d4afb6c974b9e038f4c3fdff34ce100344d8162c34e2106174ebfe8a44f5e08e24ffb654c5097fc5e5133cc9451ced46e5269126e53028517539b2aef5433027d54ca0a4a556040e255f5a4d2568a34a9571deef957b0d2555842dd5458d40e8c5964649759f3de125a8279995b1035ce5b9d11535c290acc5cb420df5d3e52365dc79d7b5e50015d5ed77c895f5e0db25fe3b38d60686cce60ec382f616f146b61f1003e6271fa6862f201ac637114cc63ef328f646c59bf64e889256563bf9165ddfbd266573cbb66cf811f6746c7d767bd0fbc683257aa68a69e806919e31f698c246b69fd614a6a6d98a36adcc9646b4af2786bb812d06c24295f6c8f351b6cf934fb6d6227f96dca0d146e30e3496e96a99c6efb5f116f5f02b16fc1938470231099708378fe70e2cbc571410804719e2cd171fa394872552c8472af05a67307c3cf735f662573b5ebd0740b53fa745f9dd074b2c8837504d3447555bd4b75a585ce75f42c0a7641af3c768e0ea576d9498877235f2c776c4eda77b417df77fab988784033287884841378c7aba17909a92c794a7c11798a23b079c89f6d7a05eeac7a4210d87a7d055a7ab6cba37aef63237b26cb4e7b5d039d7b920b887bc5e28f7bf8882f7c29fbed7c5a3d4f7c894bdd7cb727237ce3ceb17d0f42177d3980eb7d628ac57d8a5f3f7db0fdf77dd6668e7dfa98a77e1d93e97e3f57fe7e5fe4927e7f39567e9d55fb7eba3a387ed5e5c57ef0585f7f0991c37f2191b37f3857f57f4de4507f62368e7f754e7f7f872bf27f97cebc7fa736b37fb563b27fc255957fce0c3d7fd8878d7fe1c76a7fe9cbbf7ff094777ff621817ffa72d07ffd88597fff62157fffffff +} + +#define constant WAD = 0x0de0b6b3a7640000 +#define constant I32_MAX = 0x7fffffff + +//////////////////////////////////////////////////////////////// +// BASIC TRIG // +//////////////////////////////////////////////////////////////// + +/// @notice Return the sine of a value, specified in radians scaled by 1e18 +/// @dev This algorithm for converting sine only uses integer values, and it works by dividing the +/// circle into 30 bit angles, i.e. there are 1,073,741,824 (2^30) angle units, instead of the +/// standard 360 degrees (2pi radians). From there, we get an output in range -2,147,483,647 to +/// 2,147,483,647, (which is the max value of an int32) which is then converted back to the standard +/// range of -1 to 1, again scaled by 1e18 +/// @param _angle Angle to convert +/// @return Result scaled by 1e18 +#define macro SIN() = takes (1) returns (1) { + // Input stack: [angle] + + // Convert angle from from arbitrary radian value (range of 0 to 2pi) to the algorithm's range + // of 0 to 1,073,741,824 + [TWO_PI] dup1 // [TWO_PI, TWO_PI, angle] + swap2 // [angle, TWO_PI, TWO_PI] + mod // [angle % TWO_PI, TWO_PI] + [ANGLES_IN_CYCLE] mul // [ANGLES_IN_CYCLE * (angle % TWO_PI), TWO_PI] + div // [ANGLES_IN_CYCLE * (angle % TWO_PI) / TWO_PI] + // [angle] + + // Apply a mask on an integer to extract a certain number of bits, where angle is the integer + // whose bits we want to get, the width is the width of the bits (in bits) we want to extract, + // and the offset is the offset of the bits (in bits) we want to extract. The result is an + // integer containing _width bits of _value starting at the offset bit + dup1 // [angle, angle] + [INTERP_OFFSET] shr // [angle >> INTERP_OFFSET, angle] + 0x01 dup1 // [0x01, 0x01, angle >> INTERP_OFFSET, angle] + [INTERP_WIDTH] shl // [0x01 << INTERP_WIDTH, 0x01, angle >> INTERP_OFFSET, angle] + sub // [(0x01 << INTERP_WIDTH) - 0x01, angle >> INTERP_OFFSET, angle] + and // [interp, angle] + + dup2 // [angle, interp, angle] + [INDEX_OFFSET] shr // [angle >> INDEX_OFFSET, interp, angle] + 0x01 dup1 // [0x01, 0x01, angle >> INDEX_OFFSET, interp, angle] + [INDEX_WIDTH] shl // [0x01 << INDEX_WIDTH, 0x01, angle >> INDEX_OFFSET, interp, angle] + sub // [(0x01 << INDEX_WIDTH) - 0x01, angle >> INDEX_OFFSET, interp, angle] + and // [index, interp, angle] + + // The lookup table only contains data for one quadrant (since sin is symmetric around both + // axes), so here we figure out which quadrant we're in, then we lookup the values in the + // table then modify values accordingly + dup3 // [angle, index, interp, angle] + [QUADRANT_LOW_MASK] // [QUADRANT_LOW_MASK, angle, index, interp, angle] + and // [QUADRANT_LOW_MASK & angle, index, interp, angle] + iszero // [is_odd_quadrant, index, interp, angle] + + dup4 // [angle, is_odd_quadrant, index, interp, angle] + [QUADRANT_HIGH_MASK] // [QUADRANT_HIGH_MASK, angle, is_odd_quadrant, index, interp, angle] + and // [QUADRANT_HIGH_MASK & angle, is_odd_quadrant, index, interp, angle] + iszero iszero // [is_negative_quadrant, is_odd_quadrant, index, interp, angle] + + // Jump past updating the index if `is_odd_quadrant` is true + dup2 is_odd_q jumpi // [is_negative_quadrant, is_odd_quadrant, index, interp, angle] + + dup3 // [index, is_negative_quadrant, is_odd_quadrant, index, interp, angle] + 0x01 // [0x01, index, is_negative_quadrant, is_odd_quadrant, index, interp, angle] + [SINE_TABLE_SIZE] // [SINE_TABLE_SIZE, 0x01, index, is_negative_quadrant, is_odd_quadrant, index, interp, angle] + sub sub // [SINE_TABLE_SIZE - 0x01 - index, is_negative_quadrant, is_odd_quadrant, index, interp, angle] + swap3 pop // [is_negative_quadrant, is_odd_quadrant, index, interp, angle] + + is_odd_q: + + // We are looking for two consecutive indices in our lookup table + // Since EVM is left aligned, to read n bytes of data from idx i, we must read from `i * data_len` + `n` + // therefore, to read two entries of size entry_bytes `index * entry_bytes` + `entry_bytes * 2` + swap2 // [index, is_odd_quadrant, is_negative_quadrant, interp, angle] + 0x02 add // [index + 0x02, is_odd_quadrant, is_negative_quadrant, interp, angle] + [ENTRY_BYTES] mul // [offset1_2, is_odd_quadrant, is_negative_quadrant, interp, angle] + + // This following snippet will function for any entry_bytes <= 15 + __tablestart(SIN_LUT) // [sin_table_start, offset1_2, is_odd_quadrant, is_negative_quadrant, interp, angle] + add // [sin_table_start + offset1_2, is_odd_quadrant, is_negative_quadrant, interp, angle] + 0x20 swap1 // [sin_table_start + offset1_2, 0x20, is_odd_quadrant, is_negative_quadrant, interp, angle] + 0x00 codecopy // [is_odd_quadrant, is_negative_quadrant, interp, angle] + + 0x00 mload // [x1_2, is_odd_quadrant, is_negative_quadrant, interp, angle] + + // We now read the last two numbers of size entry_bytes from x1_2 + // in example: entry_bytes = 4; x1_2 = 0x00...12345678abcdefgh + // therefore: entry_mask = 0xFFFFFFFF + + // 0x00...12345678abcdefgh >> 8*4 = 0x00...12345678 + // 0x00...12345678 & 0xFFFFFFFF = 0x12345678 + dup1 0x20 shr // [x1_2 >> 0x20, x1_2, is_odd_quadrant, is_negative_quadrant, interp, angle] + [ENTRY_MASK] and // [x1, x1_2, is_odd_quadrant, is_negative_quadrant, interp, angle] + + // 0x00...12345678abcdefgh & 0xFFFFFFFF = 0xabcdefgh + swap1 [ENTRY_MASK] // [ENTRY_MASK, x1_2, x1, is_odd_quadrant, is_negative_quadrant, interp, angle] + and // [x2, x1, is_odd_quadrant, is_negative_quadrant, interp, angle] + + // Approximate angle by interpolating in the table, accounting for the quadrant + dup2 dup2 sub // [x2 - x1, x2, x1, is_odd_quadrant, is_negative_quadrant, interp, angle] + dup6 mul // [interp * (x2 - x1), x2, x1, is_odd_quadrant, is_negative_quadrant, interp, angle] + [INTERP_WIDTH] shr // [(interp * (x2 - x1)) >> INTERP_WIDTH, x2, x1, is_odd_quadrant, is_negative_quadrant, interp, angle] + + swap3 // [is_odd_quadrant, x2, x1, (interp * (x2 - x1)) >> INTERP_WIDTH, is_negative_quadrant, interp, angle] + is_odd jumpi // [x2, x1, (interp * (x2 - x1)) >> INTERP_WIDTH, is_negative_quadrant, interp, angle] + + is_even: + swap1 pop // [x2, (interp * (x2 - x1)) >> INTERP_WIDTH, is_negative_quadrant, interp, angle] + sub // [x2 - (interp * (x2 - x1)) >> INTERP_WIDTH, is_negative_quadrant, interp, angle] + finish jump + is_odd: + pop add // [x1 + (interp * (x2 - x1)) >> INTERP_WIDTH, is_negative_quadrant, interp, angle] + finish: + // Received stack: [sine, is_negative_quadrant, interp, angle] + swap1 // [is_negative_quadrant, sine, interp, angle] + iszero cont jumpi // [sine, interp, angle] + + // Negative 1 + 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + mul // [-sine, interp, angle] + + cont: + // Bring result from the range of -2,147,483,647 through 2,147,483,647 to -1e18 through 1e18. + // This can never overflow because sine is bounded by the above values + [WAD] mul // [1e18 * sine, interp, angle] + [I32_MAX] // [I32_MAX, 1e18 * sine, interp, angle] + swap1 sdiv // [1e18 * sine / I32_MAX, interp, angle] + + // Clean stack: + swap2 pop pop // [1e18 * sine / I32_MAX] + + // Return stack: [1e18 * sine / I32_MAX] +} + +/// @notice Return the cosine of a value, specified in radians scaled by 1e18 +/// @dev This is identical to the sin() method, and just computes the value by delegating to the +/// sin() method using the identity cos(x) = sin(x + pi/2) +/// @dev Overflow when `angle + PI_OVER_TWO > type(uint256).max` is ok, results are still accurate +/// @param _angle Angle to convert +/// @return Result scaled by 1e18 +#define macro COS() = takes (1) returns (1) { + // Input stack: [angle] + + [PI_OVER_TWO] add // [angle + pi/2] + SIN() // [result] + + // Return stack: [result] +} \ No newline at end of file diff --git a/src/math/__TEMP__qnnyckotyuxpdpeuvffbywnubcftdxsyFixedPointMath.huff b/src/math/__TEMP__qnnyckotyuxpdpeuvffbywnubcftdxsyFixedPointMath.huff new file mode 100644 index 00000000..323bcc19 --- /dev/null +++ b/src/math/__TEMP__qnnyckotyuxpdpeuvffbywnubcftdxsyFixedPointMath.huff @@ -0,0 +1,1093 @@ +#define function mulDivDown(uint256,uint256,uint256) pure returns(uint256) +#define function mulDivUp(uint256,uint256,uint256) pure returns(uint256) +#define function mulWadDown(uint256,uint256) pure returns(uint256) +#define function mulWadUp(uint256,uint256) pure returns(uint256) +#define function divWadDown(uint256,uint256) pure returns(uint256) +#define function divWadUp(uint256,uint256) pure returns(uint256) +#define function rpow(uint256,uint256,uint256) pure returns(uint256) +#define function expWad(int256) pure returns(int256) +#define function powWad(int256,int256) pure returns(int256) +#define function lnWad(int256) pure returns(int256) +#define function sqrt(uint256) pure returns(uint256) +#define function log2(uint256) pure returns(uint256) +#define function cbrt(uint256) pure returns(uint256) + +#define macro MUL_DIV_DOWN_WRAPPER(fail) = takes (0) returns (0) { + 0x44 calldataload // [denominator] + 0x24 calldataload // [y, denominator] + 0x04 calldataload // [x, y, denominator] + MUL_DIV_DOWN(fail) // [result] + 0x00 mstore // [] + 0x20 0x00 return +} + +#define macro MUL_DIV_UP_WRAPPER(fail) = takes (0) returns (0) { + 0x44 calldataload // [denominator] + 0x24 calldataload // [y, denominator] + 0x04 calldataload // [x, y, denominator] + MUL_DIV_UP(fail) // [result] + 0x00 mstore // [] + 0x20 0x00 return +} + +#define macro MUL_WAD_DOWN_WRAPPER(fail) = takes (0) returns (0) { + 0x24 calldataload // [y] + 0x04 calldataload // [x, y] + MUL_WAD_DOWN(fail) // [result] + 0x00 mstore // [] + 0x20 0x00 return +} + +#define macro MUL_WAD_UP_WRAPPER(fail) = takes (0) returns (0) { + 0x24 calldataload // [y] + 0x04 calldataload // [x, y] + MUL_WAD_UP(fail) // [result] + 0x00 mstore // [] + 0x20 0x00 return +} + +#define macro DIV_WAD_DOWN_WRAPPER(fail) = takes (0) returns (0) { + 0x24 calldataload // [y] + 0x04 calldataload // [x, y] + DIV_WAD_DOWN(fail) // [result] + 0x00 mstore // [] + 0x20 0x00 return +} + +#define macro DIV_WAD_UP_WRAPPER(fail) = takes (0) returns (0) { + 0x24 calldataload // [y] + 0x04 calldataload // [x, y] + DIV_WAD_UP(fail) // [result] + 0x00 mstore // [] + 0x20 0x00 return +} + +#define macro RPOW_WRAPPER(fail) = takes (0) returns (0) { + 0x44 calldataload // [scalar] + 0x24 calldataload // [n, scalar] + 0x04 calldataload // [x, n, scalar] + RPOW(fail) // [result] + 0x00 mstore // [] + 0x20 0x00 return +} + +#define macro EXP_WAD_WRAPPER(fail) = takes (0) returns (0) { + 0x04 calldataload // [x] + EXP_WAD(fail) // [result] + 0x00 mstore + 0x20 0x00 return +} + +#define macro LN_WAD_WRAPPER(fail) = takes (0) returns (0) { + 0x04 calldataload // [x] + LN_WAD(fail) // [result] + 0x00 mstore + 0x20 0x00 return +} + +#define macro POW_WAD_WRAPPER(fail) = takes (0) returns (0) { + 0x24 calldataload // [y] + 0x04 calldataload // [x, y] + POW_WAD(fail) // [result] + 0x00 mstore // [] + 0x20 0x00 return +} + +#define macro SQRT_WRAPPER() = takes (0) returns (0) { + 0x04 calldataload // [x] + SQRT() // [result] + 0x00 mstore + 0x20 0x00 return +} + +#define macro LOG_2_WRAPPER(fail) = takes (0) returns (0) { + 0x04 calldataload // [x] + LOG_2(fail) // [result] + 0x00 mstore + 0x20 0x00 return +} + +#define macro CBRT_WRAPPER() = takes (0) returns (0) { + 0x04 calldataload + CBRT() + 0x00 mstore + 0x20 0x00 return +} + +#define macro MAIN() = takes (0) returns (0) { + pc calldataload 0xE0 shr + dup1 __FUNC_SIG(mulDivDown) eq mulDivDown jumpi + dup1 __FUNC_SIG(mulDivUp) eq mulDivUp jumpi + dup1 __FUNC_SIG(mulWadDown) eq mulWadDown jumpi + dup1 __FUNC_SIG(mulWadUp) eq mulWadUp jumpi + dup1 __FUNC_SIG(divWadDown) eq divWadDown jumpi + dup1 __FUNC_SIG(divWadUp) eq divWadUp jumpi + dup1 __FUNC_SIG(rpow) eq rpow jumpi + dup1 __FUNC_SIG(expWad) eq expWad jumpi + dup1 __FUNC_SIG(lnWad) eq lnWad jumpi + dup1 __FUNC_SIG(powWad) eq powWad jumpi + dup1 __FUNC_SIG(sqrt) eq sqrt jumpi + dup1 __FUNC_SIG(log2) eq logTwo jumpi + dup1 __FUNC_SIG(cbrt) eq cbrt jumpi + + + fail: + 0x00 0x00 revert + mulDivDown: + MUL_DIV_DOWN_WRAPPER(fail) + mulDivUp: + MUL_DIV_UP_WRAPPER(fail) + mulWadDown: + MUL_WAD_DOWN_WRAPPER(fail) + mulWadUp: + MUL_WAD_UP_WRAPPER(fail) + divWadDown: + DIV_WAD_DOWN_WRAPPER(fail) + divWadUp: + DIV_WAD_UP_WRAPPER(fail) + rpow: + RPOW_WRAPPER(fail) + expWad: + EXP_WAD_WRAPPER(fail) + lnWad: + LN_WAD_WRAPPER(fail) + powWad: + POW_WAD_WRAPPER(fail) + sqrt: + SQRT_WRAPPER() + logTwo: + LOG_2_WRAPPER(fail) + cbrt: + CBRT_WRAPPER() +} + +/// @title FixedPointMath +/// @notice SPDX-License-Identifier: MIT +/// @author clabby +/// @notice Minimal module for fixed-point number arithmetic +/// @notice Adapted from Solmate (https://github.com/transmissions11/solmate/blob/v7/src/utils/FixedPointMathLib.sol) + +#define constant WAD = 0x0de0b6b3a7640000 +#define constant DAY = 0x15180 + +//////////////////////////////////////////////////////////////// +// SIMPLIFIED FIXED POINT OPERATIONS // +//////////////////////////////////////////////////////////////// + +// https://github.com/transmissions11/solmate/blob/v7/src/utils/FixedPointMathLib.sol#L13 +#define macro MUL_WAD_DOWN(fail) = takes (2) returns (1) { + // Input stack: [x, y] + [WAD] // [WAD, x, y] + ARRANGE_STACK_MULWAD() // [x, y, WAD] + MUL_DIV_DOWN(fail) // [result] +} + +// https://github.com/transmissions11/solmate/blob/v7/src/utils/FixedPointMathLib.sol#L17 +#define macro MUL_WAD_UP(fail) = takes (2) returns (1) { + // Input stack: [x, y] + [WAD] // [WAD, x, y] + ARRANGE_STACK_MULWAD() // [x, y, WAD] + MUL_DIV_UP(fail) // [result] +} + +// https://github.com/transmissions11/solmate/blob/v7/src/utils/FixedPointMathLib.sol#L21 +#define macro DIV_WAD_DOWN(fail) = takes (2) returns (1) { + // Input stack: [x, y] + [WAD] // [WAD, x, y] + ARRANGE_STACK_DIVWAD() // [x, WAD, y] + MUL_DIV_DOWN(fail) +} + +// https://github.com/transmissions11/solmate/blob/v7/src/utils/FixedPointMathLib.sol#L25 +#define macro DIV_WAD_UP(fail) = takes (2) returns (1) { + // Input stack: [x, y] + [WAD] // [WAD, x, y] + ARRANGE_STACK_DIVWAD() // [x, WAD, y] + MUL_DIV_UP(fail) // [result] +} + +// https://github.com/transmissions11/solmate/blob/v7/src/utils/FixedPointMathLib.sol#L34 +#define macro EXP_WAD(fail) = takes (1) returns (1) { + // Input stack: [x] + + // When the result is < 0.5 we return zero. This happens when + // x <= floor(log(0.5e18) * 1e18) ~ -42e18 + 0xfffffffffffffffffffffffffffffffffffffffffffffffdb731c958f34d94c1 + dup2 // [x, 0xfff..., x] + sgt iszero // [x <= 0xfff..., x] + ret_zero jumpi // [x] + + // When the result is > (2**255 - 1) / 1e18 we can not represent it as an + // int. This happens when x >= floor(log((2**255 - 1) / 1e18) * 1e18) ~ 135. + 0x0755bf798b4a1bf1e5 // [0x0755bf798b4a1bf1e5, x] + dup2 // [x, 0x0755bf798b4a1bf1e5, x] + slt iszero // [x >= 0x0755bf798b4a1bf1e5, x] + jumpi // [x] + + // x is now in the range (-42, 136) * 1e18. Convert to (-42, 136) * 2**96 + // for more intermediate precision and a binary basis. This base conversion + // is a multiplication by 1e18 / 2**96 = 5**18 / 2**78. + 0x03782dace9d9 // [0x05 ** 0x12, x] + swap1 // [x, 0x05 ** 0x12] + 0x4e shl // [x << 0x4e, 0x05 ** 0x12] + sdiv // [x << 0x4e / 0x05 ** 0x12] + + // Reduce range of x to (-1/2 ln 2, 1/2 ln 2) * 2**96 by factoring out powers + // of two such that exp(x) = exp(x') * 2**k, where k is an integer. + // Solving this gives k = round(x / log(2)) and x' = x - k * log(2). + 0xb17217f7d1cf79abc9e3b398 + dup2 // [x, 0xb17217f7d1cf79abc9e3b398, x] + 0x60 shl // [x << 96, 0xb17217f7d1cf79abc9e3b398, x] + sdiv // [x << 96 / 0xb17217f7d1cf79abc9e3b398, x] + 0x7ffffff20f9306d2eea00000 // [2**95, x << 96 / 0xb17217f7d1cf79abc9e3b398, x] + add // [2**95 + x << 96 / 0xb17217f7d1cf79abc9e3b398, x] + 0x60 sar // [(2**95 + x << 96 / 0xb17217f7d1cf79abc9e3b398) >> 96, x] + + dup1 // [(2**95 + x << 96 / 0xb17217f7d1cf79abc9e3b398) >> 96, (2**95 + x << 96 / 0xb17217f7d1cf79abc9e3b398) >> 96, x] + 0xb17217f7d1cf79abc9e3b398 + mul // [((2**95 + x << 96 / 0xb17217f7d1cf79abc9e3b398) >> 96) * 0xb17217f7d1cf79abc9e3b398, (2**95 + x << 96 / 0xb17217f7d1cf79abc9e3b398) >> 96, x] + dup3 // [x, ((2**95 + x << 96 / 0xb17217f7d1cf79abc9e3b398) >> 96) * 0xb17217f7d1cf79abc9e3b398, (2**95 + x << 96 / 0xb17217f7d1cf79abc9e3b398) >> 96, x] + sub // [x (new), (2**95 + x << 96 / 0xb17217f7d1cf79abc9e3b398) >> 96, x] + swap2 pop // [k, x] + + // k is in the range [-61, 195]. + + // Evaluate using a (6, 7)-term rational approximation. + // p is made monic, we'll multiply by a scale factor later. + 0x10fe68e7fd37d0007b713f7650 + dup3 // [x, 0x10fe68e7fd37d0007b713f7650, k, x] + add // [y, k, x] + + 0x02d16720577bd19bf614176fe9ea + dup2 dup5 mul // [x * y, 0x02d16720577bd19bf614176fe9ea, y, k, x] + 0x60 sar // [(x * y) >> 0x60, 0x02d16720577bd19bf614176fe9ea, y, k, x] + add // [((x * y) >> 0x60) + 0x02d16720577bd19bf614176fe9ea, y, k, x] + swap1 pop // [y, k, x] + + 0x04a4fd9f2a8b96949216d2255a6c + dup4 dup3 add // [x + y, 0x04a4fd9f2a8b96949216d2255a6c, y, k, x] + sub // [x + y - 0x04a4fd9f2a8b96949216d2255a6c, y, k, x] + + dup2 // [y, x + y - 0x04a4fd9f2a8b96949216d2255a6c, y, k, x] + mul // [y * (x + y - 0x04a4fd9f2a8b96949216d2255a6c), y, k, x] + 0x60 sar // [(y * (x + y - 0x04a4fd9f2a8b96949216d2255a6c)) >> 0x60, y, k, x] + 0x0587f503bb6ea29d25fcb740196450 + add // [p, y, k, x] + + dup4 // [x, p, y, k, x] + mul // [x * p, y, k, x] + 0xd835ebba824c98fb31b83b2ca45c + 0x60 shl // [0xd835ebba824c98fb31b83b2ca45c << 0x60, x * p, y, k, x] + add // [p, y, k, x] + + // We leave p in 2**192 basis so we don't need to scale it back up for the division. + + 0x240c330e9fb2d9cbaf0fd5aafc + dup5 sub // [q, p, y, k, x] + + dup5 mul // [x * q, p, y, k, x] + 0x60 sar // [(x * q) >> 0x60, p, y, k, x] + 0x0277594991cfc85f6e2461837cd9 + add // [q, p, y, k, x] + + dup5 mul // [x * q, p, y, k, x] + 0x60 sar // [(x * q) >> 0x60, p, y, k, x] + 0x1a521255e34f6a5061b25ef1c9c4 swap1 + sub // [q, p, y, k, x] + + dup5 mul // [x * q, p, y, k, x] + 0x60 sar // [(x * q) >> 0x60, p, y, k, x] + 0xb1bbb201f443cf962f1a1d3db4a5 + add // [q, p, y, k, x] + + dup5 mul // [x * q, p, y, k, x] + 0x60 sar // [(x * q) >> 0x60, p, y, k, x] + 0x02c72388d9f74f51a9331fed693f15 swap1 + sub // [q, p, y, k, x] + + dup5 mul // [x * q, p, y, k, x] + 0x60 sar // [(x * q) >> 0x60, p, y, k, x] + 0x05180bb14799ab47a8a8cb2a527d57 + add // [q, p, y, k, x] + + // The q polynomial won't have zeros in the domain as all its roots are complex. + // No scaling is necessary because p is already 2**96 too large. + swap1 sdiv // [p / q (r), y, k, x] + + // r should be in the range (0.09, 0.25) * 2**96. + + // We now need to multiply r by: + // * the scale factor s = ~6.031367120. + // * the 2**k factor from the range reduction. + // * the 1e18 / 2**96 factor for base conversion. + // We do this all at once, with an intermediate result in 2**213 + // basis, so the final right shift is always by a positive amount. + + 0x029d9dc38563c32e5c2f6dc192ee70ef65f9978af3 + mul // [0x029d9... * r, y, k, x] + dup3 // [k, 0x029d9... * r, y, k, x] + 0xc3 sub // [0xc3 - k, 0x029d9... * r, y, k, x] + shr // [(0x029d9... * r) >> 0xc3 - k, y, k, x] + + // Clean stack + swap3 pop pop pop // [result] + + finish jump + + ret_zero: + 0x00 dup1 mstore + 0x20 0x00 return + finish: + // Return stack: [result] +} + +// https://github.com/transmissions11/solmate/blob/v7/src/utils/FixedPointMathLib.sol#L92 +#define macro LN_WAD(fail) = takes (1) returns (1) { + // Input stack: [x] + 0x00 dup2 sgt // [x > 0, x] + iszero // [x <= 0, x] + jumpi // [x] + + // We want to convert x from 10**18 fixed point to 2**96 fixed point. + // We do this by multiplying by 2**96 / 10**18. But since + // ln(x * C) = ln(x) + ln(C), we can simply do nothing here + // and add ln(2**96 / 10**18) at the end. + + // Reduce range of x to (1, 2) * 2**96 + // ln(2^k * x) = k * ln(2) + ln(x) + 0x60 // [0x60, x] + dup2 LOG_2(fail) // [log2(x), 0x60, x] + sub // [k, x] + + dup2 dup2 // [k, x, k, x] + 0x9f sub // [0x9f - k, x, k, x] + shl // [x << (0x9f - k), k, x] + 0x9f shr // [x_new, k, x] + swap2 pop // [k, x] + + // Evaluate using a (8, 8)-term rational approximation. + // p is made monic, we will multiply by a scale factor later. + dup2 // [x, k, x] + 0x29508e458543d8aa4df2abee78 + add // [p, k, x] + + dup3 mul // [p * x, k, x] + 0x60 sar // [(p * x) >> 0x60, k, x] + 0x0139601a2efabe717e604cbb4894 + add // [p, k, x] + + dup3 mul // [p * x, k, x] + 0x60 sar // [(p * x) >> 0x60, k, x] + 0x02247f7a7b6594320649aa03aba1 + add // [p, k, x] + + 0x8c3f38e95a6b1ff2ab1c3b3437 + swap1 dup4 mul // [p * x, 0x8c3f..., k, x] + 0x60 sar // [(p * x) >> 0x60, 0x8c3f..., k, x] + sub // [p, k, x] + + 0x02384773bdf1ac5676facced6091 + swap1 dup4 mul // [p * x, 0x0238..., k, x] + 0x60 sar // [(p * x) >> 0x60, 0x0238..., k, x] + sub // [p, k, x] + + 0xb9a025d814b29c212b8b1a07ce + swap1 dup4 mul // [p * x, 0xb9a0..., k, x] + 0x60 sar // [(p * x) >> 0x60, 0xb9a0..., k, x] + sub // [p, k, x] + + 0x0a09507084cc699bb0e71ea86a + 0x60 shl // [0x0a09... << 0x60, p, k, x] + swap1 // [p, 0x0a09... << 0x60, k, x] + dup4 mul // [p * x, 0x0a09... << 0x60, k, x] + sub // [p, k, x] + + // We leave p in 2**192 basis so we don't need to scale it back up for the division. + // q is monic by convention. + dup3 // [x, p, k, x] + 0x465772b2bbbb5f824b15207a30 + add // [q, p, k, x] + + dup4 mul // [q * x, p, k, x] + 0x60 sar // [(q * x) >> 0x60, p, k, x] + 0x0388eaa27412d5aca026815d636e + add // [q, p, k, x] + + dup4 mul // [q * x, p, k, x] + 0x60 sar // [(q * x) >> 0x60, p, k, x] + 0x0df99ac502031bf953eff472fdcc + add // [q, p, k, x] + + dup4 mul // [q * x, p, k, x] + 0x60 sar // [(q * x) >> 0x60, p, k, x] + 0x13cdffb29d51d99322bdff5f2211 + add // [q, p, k, x] + + dup4 mul // [q * x, p, k, x] + 0x60 shr // [(q * x) >> 0x60, p, k, x] + 0x0a0f742023def783a307a986912e + add // [q, p, k, x] + + dup4 mul // [q * x, p, k, x] + 0x60 sar // [(q * x) >> 0x60, p, k, x] + 0x01920d8043ca89b5239253284e42 + add // [q, p, k, x] + + dup4 mul // [q * x, p, k, x] + 0x60 sar // [(q * x) >> 0x60, p, k, x] + 0x0b7a86d7375468fac667a0a527 + add // [q, p, k, x] + + // The q polynomial is known not to have zeros in the domain. + // No scaling required because p is already 2**96 too large. + swap1 sdiv // [p / q (r), k, x] + + // r is in the range (0, 0.125) * 2**96 + + // Finalization, we need to: + // * multiply by the scale factor s = 5.549... + // * add ln(2**96 / 10**18) + // * add k * ln(2) + // * multiply by 10**18 / 2**96 = 5**18 >> 78 + + // mul s * 5e18 * 2**96, base is now 5**18 * 2**192 + 0x1340daa0d5f769dba1915cef59f0815a5506 mul + + // add ln(2) * k * 5e18 * 2**192 + swap1 // [k, r, x] + 0x0267a36c0c95b3975ab3ee5b203a7614a3f75373f047d803ae7b6687f2b3 + mul // [k * 0x0267..., r, x] + add // [r, x] + + // add ln(2**96 / 10**18) * 5e18 * 2**192 + 0x57115e47018c7177eebf7cd370a3356a1b7863008a5ae8028c72b8864284 + add // [r, x] + + // base conversion: mul 2**18 / 2**192 + 0xAE sar // [r >> 0xAE, x] + + finish jump + + finish: + // Clean stack + swap1 pop + // Return stack: [result] +} + +// https://github.com/transmissions11/solmate/blob/v7/src/utils/FixedPointMathLib.sol#L29 +#define macro POW_WAD(fail) = takes (2) returns (1) { + // Input Stack: [x, y] + LN_WAD(fail) // [lnWad(x), y] + mul // [lnWad(x) * y] + [WAD] swap1 // [lnWad(x) * y, 1e18] + sdiv // [(lnWad(x) * y) / 1e18] + EXP_WAD(fail) // [result] +} + +//////////////////////////////////////////////////////////////// +// LOW LEVEL FIXED POINT OPERATIONS // +//////////////////////////////////////////////////////////////// + +// https://github.com/transmissions11/solmate/blob/main/src/utils/FixedPointMathLib.sol#L34 +#define macro MUL_DIV_DOWN(fail) = takes (3) returns (1) { + // Input stack: [x, y, denominator] + dup1 dup3 mul // [x * y, x, y, denominator] + dup1 // [x * y, x * y, x, y, denominator] + swap2 dup1 // [x, x, x * y, x * y, y, denominator] + + iszero // [x == 0, x, x * y, x * y, y, denominator] + swap2 // [x * y, x, x == 0, x * y, y, denominator] + div // [(x * y) / x, x == 0, x * y, y, denominator] + dup4 eq // [y == (x * y) / x, x == 0, x * y, y, denominator] + or // [y == (x * y) / x | x == 0, x * y, y, denominator] + swap2 pop // [x * y, y == (x * y) / x | x == 0, denominator] + swap1 dup3 // [denominator, y == (x * y) / x | x == 0, x * y, denominator] + iszero iszero // [denominator != 0, y == (x * y) / x | x == 0, x * y, denominator] + and // [denominator != 0 & y == (x * y) / x | x == 0, x * y, denominator] + + iszero jumpi // [x * y, denominator] + + div // [(x * y) / denominator] + // Return stack: [(x * y) / denominator] +} + +// https://github.com/transmissions11/solmate/blob/main/src/utils/FixedPointMathLib.sol#L53 +#define macro MUL_DIV_UP(fail) = takes (3) returns (1) { + // Input stack: [x, y, denominator] + dup1 dup3 mul // [x * y, x, y, denominator] + dup1 // [x * y, x * y, x, y, denominator] + swap2 dup1 // [x, x, x * y, x * y, y, denominator] + + iszero // [x == 0, x, x * y, x * y, y, denominator] + swap2 // [x * y, x, x == 0, x * y, y, denominator] + div // [(x * y) / x, x == 0, x * y, y, denominator] + dup4 eq // [y == (x * y) / x, x == 0, x * y, y, denominator] + or // [y == (x * y) / x | x == 0, x * y, y, denominator] + swap2 pop // [x * y, y == (x * y) / x | x == 0, denominator] + swap1 dup3 // [denominator, y == (x * y) / x | x == 0, x * y, denominator] + iszero iszero // [denominator != 0, y == (x * y) / x | x == 0, x * y, denominator] + and // [denominator != 0 & y == (x * y) / x | x == 0, x * y, denominator] + + iszero jumpi // [x * y, denominator] + + dup1 // [x * y, x * y, denominator] + iszero iszero // [x * y != 0, x * y, denominator] + + dup3 // [denominator, x * y != 0, x * y, denominator] + 0x01 // [1, denominator, x * y != 0, x * y, denominator] + dup4 // [x * y, 1, denominator, x * y != 0, x * y, denominator] + sub // [x * y - 1, denominator, x * y != 0, x * y, denominator] + div // [x * y - 1 / denominator, x * y != 0, x * y, denominator] + 0x01 // [1, x * y - 1 / denominator, x * y != 0, x * y, denominator] + add // [(x * y - 1 / denominator) + 1, x * y != 0, x * y, denominator] + + mul // [((x * y - 1 / denominator) + 1) * (x * y != 0), x * y, denominator] + + // Clear extra stack items before continuing + swap2 // [denominator, x * y, ((x * y - 1 / denominator) + 1) * (x * y != 0)] + pop pop // [((x * y - 1 / denominator) + 1) * (x * y != 0)] + // Return stack: [((x * y - 1 / denominator) + 1) * (x * y != 0)] +} + +// https://github.com/transmissions11/solmate/blob/main/src/utils/FixedPointMathLib.sol#L74 +// TODO: Optimize, works but not great +#define macro RPOW(fail) = takes (3) returns (1) { + // Input stack: [x, n, scalar] + dup1 // [x, x, n, scalar] + default jumpi // Jump to "default" if x != 0 + + // TODO: Fix hack- code following `finish` label pops four items off of + // the stack, so we fill it with extra items here in order to return + // the scalar or 0. + + dup3 dup4 // [scalar, scalar, x, n, scalar] + dup4 iszero // [n == 0, scalar, scalar, x, n, scalar] + finish jumpi // If n == 0 && x == 0, return the scalar (0 ** 0 = 1). + + // 0 ** n = 0 + 0x00 dup1 finish jump // Finish execution + + default: + dup3 // [scalar, x, n, scalar] + 0x01 shr // [scalar >> 1, x, n, scalar] + + dup4 // [result, scalar >> 1, x, n, scalar] + 0x02 // [2, result, scalar >> 1, x, n, scalar] + dup5 // [n, 2, result, scalar >> 1, x, n, scalar] + mod // [n % 2, result, scalar >> 1, x, n, scalar] + + // Set result to scalar for now if n % 2 is even + iszero loop jumpi // [result, scalar >> 1, x, n, scalar]] + + // Set result to x for now if n % 2 is odd + pop dup2 // [result, scalar >> 1, x, n, scalar] + loop: + dup4 // [n, result, scalar >> 1, x, n, scalar] + iszero finish jumpi // If n == 0, the loop is finished. + + // Divide n by 2 + dup4 // [n, result, scalar >> 1, x, n, scalar] + 0x01 shr // [n >> 1, result, scalar >> 1, x, n, scalar] + swap4 pop // [result, scalar >> 1, x, n, scalar] + + // Revert if x ** 2 will overflow. + dup3 // [x, result, scalar >> 1, x, n, scalar] + 0x80 shr // [x >> 128, result, scalar >> 1, x, n, scalar] + + // Square x and duplicate it on the stack for use later. + dup4 // [x, x >> 128, result, scalar >> 1, x, n, scalar] + dup1 mul // [x * x, x >> 128, result, scalar >> 1, x, n, scalar] + dup1 // [x * x, x * x, x >> 128, result, scalar >> 1, x, n, scalar] + + // Add x ** 2 to scalar >> 1 + dup5 // [scalar >> 1, x * x, x * x, x >> 128, result, scalar >> 1, x, n, scalar] + add // [(scalar >> 1) + (x * x), x * x, x >> 128, result, scalar >> 1, x, n, scalar] + + // Revert if x ** 2 + scalar >> 1 overflowed + swap2 // [x >> 128, x * x, (scalar >> 1) + (x * x), result, scalar >> 1, x, n, scalar] + swap1 // [x * x, x >> 128, (scalar >> 1) + (x * x), result, scalar >> 1, x, n, scalar] + dup3 lt // [(scalar >> 1) + (x * x) < x * x, x >> 128, (scalar >> 1) + (x * x), result, scalar >> 1, x, n, scalar] + or jumpi // [(scalar >> 1) + (x * x), result, scalar >> 1, x, n, scalar] + + // Set x to ((scalar >> 1) + (x * x)) / scalar + dup6 // [scalar, (scalar >> 1) + (x * x), result, scalar >> 1, x, n, scalar] + swap1 // [(scalar >> 1) + (x * x), scalar, result, scalar >> 1, x, n, scalar] + div // [((scalar >> 1) + (x * x)) / scalar, result, scalar >> 1, x, n, scalar] + swap3 pop // [result, scalar >> 1, x, n, scalar] + + 0x02 // [2, result, scalar >> 1, x, n, scalar] + dup5 // [n, 2, result, scalar >> 1, x, n, scalar] + mod // [n % 2, result, scalar >> 1, x, n, scalar] + + // If n is even, continue loop + iszero loop jumpi + // If n is odd, continue logic + + // Multiply x * result + dup1 // [result, result, scalar >> 1, x, n, scalar] + dup4 // [x, result, result, scalar >> 1, x, n, scalar] + mul // [x * result, result, scalar >> 1, x, n, scalar] + dup1 // [x * result, x * result, result, scalar >> 1, x, n, scalar] + dup1 // [x * result, x * result, x * result, result, scalar >> 1, x, n, scalar] + + // Check if x * result overflowed + dup6 // [x, x * result, x * result, x * result, result, scalar >> 1, x, n, scalar] + swap1 // [x * result, x, x * result, x * result, result, scalar >> 1, x, n, scalar] + div // [x * result / x, x * result, x * result, result, scalar >> 1, x, n, scalar] + dup4 // [result, x * result / x, x * result, x * result, result, scalar >> 1, x, n, scalar] + eq iszero // [result != (x * result / x), x * result, x * result, result, scalar >> 1, x, n, scalar] + dup6 // [x, result != (x * result / x), x * result, x * result, result, scalar >> 1, x, n, scalar] + iszero iszero // [x != 0, result != (x * result / x), x * result, x * result, result, scalar >> 1, x, n, scalar] + and // [x != 0 & result != (x * result / x), x * result, x * result, result, scalar >> 1, x, n, scalar] + swap2 // [x * result, x * result, x != 0 & result != (x * result / x), result, scalar >> 1, x, n, scalar] + + // Round to the nearest number + dup5 // [scalar >> 1, x * result, x * result, x != 0 & result != (x * result / x), result, scalar >> 1, x, n, scalar] + add // [(scalar >> 1) + (x * result), x * result, x != 0 & result != (x * result / x), result, scalar >> 1, x, n, scalar] + + // Check if x ** 2 + scalar >> 1 overflowed + swap2 // [x != 0 & result != (x * result / x), x * result, (scalar >> 1) + (x * result), result, scalar >> 1, x, n, scalar] + swap1 // [x * result, x != 0 & result != (x * result / x), (scalar >> 1) + (x * result), result, scalar >> 1, x, n, scalar] + dup3 lt // [(scalar >> 1) + (x * result) < x * result, x != 0 & result != (x * result / x), (scalar >> 1) + (x * result), result, scalar >> 1, x, n, scalar] + + // Revert if ((scalar >> 1) + (x * result)) < x * result OR x != 0 & result != (x * result / x) + or jumpi // [(scalar >> 1) + (x * result), result, scalar >> 1, x, n, scalar] + + // Scale rounded result + dup6 // [scalar, (scalar >> 1) + (x * result), result, scalar >> 1, x, n, scalar] + swap1 // [(scalar >> 1) + (x * result), scalar, result, scalar >> 1, x, n, scalar] + div // [(scalar >> 1) + (x * result)) / scalar, result, scalar >> 1, x, n, scalar] + swap1 pop // [result, scalar >> 1, x, n, scalar] + + loop jump // Continue loop + // Return result + finish: + // Clean Stack + swap4 // [scalar, scalar >> 1, x, n, result] + pop pop pop pop // [result] + // Return stack: [result] +} + +//////////////////////////////////////////////////////////////// +// GENERAL NUMBER UTILITIES // +//////////////////////////////////////////////////////////////// + +// https://github.com/transmissions11/solmate/blob/v7/src/utils/FixedPointMathLib.sol#L288 +#define macro SQRT() = takes (1) returns (1) { + // Input stack: [x] + + // We start y at x, which will help us make our initial estimate. + dup1 // [y, x] + + // The "correct" value is 1, but this saves a multiplication later. + 0xb5 // [0xb5, y, x] + + 0x10000000000000000000000000000000000 + dup3 // [y, 0x1000..., z, y, x] + lt // [y < 0x1000..., z, y, x] + continue_1 jumpi // [z, y, x] + + 0x40 shl // [z << 0x40, y, x] + swap1 // [y, z << 0x40, x] + 0x80 shr // [y >> 0x80, z << 0x40, x] + swap1 // [z << 0x40, y >> 0x80, x] + + continue_1: + + 0x1000000000000000000 + dup3 // [y, 0x1000..., z, y, x] + lt // [y < 0x1000..., z, y, x] + continue_2 jumpi // [z, y, x] + + 0x20 shl // [z << 0x20, y, x] + swap1 // [y, z << 0x20, x] + 0x40 shr // [y >> 0x40, z << 0x20, x] + swap1 // [z << 0x20, y >> 0x40, x] + + continue_2: + + 0x10000000000 + dup3 // [y, 0x1000..., z, y, x] + lt // [y < 0x1000..., z, y, x] + continue_3 jumpi // [z, y, x] + + 0x10 shl // [z << 0x10, y, x] + swap1 // [y, z << 0x10, x] + 0x20 shr // [y >> 0x20, z << 0x10, x] + swap1 // [z << 0x10, y >> 0x20, x] + + continue_3: + + 0x1000000 + dup3 // [y, 0x1000..., z, y, x] + lt // [y < 0x1000..., z, y, x] + continue_4 jumpi // [z, y, x] + + 0x08 shl // [z << 0x08, y, x] + swap1 // [y, z << 0x08, x] + 0x10 shr // [y >> 0x10, z << 0x08, x] + swap1 // [z << 0x08, y >> 0x10, x] + + continue_4: + + // Goal was to get z*z*y within a small factor of x. More iterations could + // get y in a tighter range. Currently, we will have y in [256, 256*2^16). + // We ensured y >= 256 so that the relative difference between y and y+1 is small. + // That's not possible if x < 256 but we can just verify those cases exhaustively. + + // Now, z*z*y <= x < z*z*(y+1), and y <= 2^(16+8), and either y >= 256, or x < 256. + // Correctness can be checked exhaustively for x < 256, so we assume y >= 256. + // Then z*sqrt(y) is within sqrt(257)/sqrt(256) of sqrt(x), or about 20bps. + + // For s in the range [1/256, 256], the estimate f(s) = (181/1024) * (s+1) is in the range + // (1/2.84 * sqrt(s), 2.84 * sqrt(s)), with largest error when s = 1 and when s = 256 or 1/256. + + // Since y is in [256, 256*2^16), let a = y/65536, so that a is in [1/256, 256). Then we can estimate + // sqrt(y) using sqrt(65536) * 181/1024 * (a + 1) = 181/4 * (y + 65536)/65536 = 181 * (y + 65536)/2^18. + + // There is no overflow risk here since y < 2^136 after the first branch above. + + // A mul is saved from starting z at 181. + swap1 // [y, z, x] + 0x010000 add // [y + 0x010000, z, x] + mul // [(y + 0x010000) * z, x] + 0x12 shr // [((y + 0x010000) * z) >> 0x12, x] + + // Given the worst case multiplicative error of 2.84 above, 7 iterations should be enough. + dup1 dup3 // [x, z, z, x] + div // [x / z, z, x] + add // [x / z + z, x] + 0x01 shr // [(x / z + z) >> 0x01, x] + + dup1 dup3 // [x, z, z, x] + div // [x / z, z, x] + add // [x / z + z, x] + 0x01 shr // [(x / z + z) >> 0x01, x] + + dup1 dup3 // [x, z, z, x] + div // [x / z, z, x] + add // [x / z + z, x] + 0x01 shr // [(x / z + z) >> 0x01, x] + + dup1 dup3 // [x, z, z, x] + div // [x / z, z, x] + add // [x / z + z, x] + 0x01 shr // [(x / z + z) >> 0x01, x] + + dup1 dup3 // [x, z, z, x] + div // [x / z, z, x] + add // [x / z + z, x] + 0x01 shr // [(x / z + z) >> 0x01, x] + + dup1 dup3 // [x, z, z, x] + div // [x / z, z, x] + add // [x / z + z, x] + 0x01 shr // [(x / z + z) >> 0x01, x] + + dup1 dup3 // [x, z, z, x] + div // [x / z, z, x] + add // [x / z + z, x] + 0x01 shr // [(x / z + z) >> 0x01, x] + + // If x+1 is a perfect square, the Babylonian method cycles between + // floor(sqrt(x)) and ceil(sqrt(x)). This statement ensures we return floor. + // See: https://en.wikipedia.org/wiki/Integer_square_root#Using_only_integer_division + // Since the ceil is rare, we save gas on the assignment and repeat division in the rare case. + // If you don't care whether the floor or ceil square root is returned, you can remove this statement. + dup1 dup1 swap3 // [x, z, z, z] + div // [x / z, z, z] + lt // [(x / z) < z, z] + swap1 sub // [z - (x / z) < z] +} + +// https://github.com/transmissions11/solmate/blob/v7/src/utils/FixedPointMathLib.sol#L352 +#define macro LOG_2(fail) = takes (1) returns (1) { + // Input stack: [x] + + dup1 iszero // [x == 0, x] + jumpi // [x] + + dup1 // [x, x] + 0xffffffffffffffffffffffffffffffff + lt // [0xffff... < x, x] + 0x07 shl // [r, x] + + dup2 dup2 // [r, x, r, x] + shr // [x >> r, r, x] + 0xffffffffffffffff lt // [0xffff... < (x >> r), r, x] + 0x06 shl // [(0xffff... < (x >> r)) << 6, r, x] + or // [r | (0xffff... < (x >> r)) << 6, x] + + dup2 dup2 // [r, x, r, x] + shr // [x >> r, r, x] + 0xffffffff lt // [0xffff... < (x >> r), r, x] + 0x05 shl // [(0xffff... < (x >> r)) << 5, r, x] + or // [r | (0xffff... < (x >> r)) << 5, x] + + dup2 dup2 // [r, x, r, x] + shr // [x >> r, r, x] + 0xffff lt // [0xffff < (x >> r), r, x] + 0x04 shl // [(0xffff < (x >> r)) << 4, r, x] + or // [r | (0xffff < (x >> r)) << 4, x] + + dup2 dup2 // [r, x, r, x] + shr // [x >> r, r, x] + 0xff lt // [0xff < (x >> r), r, x] + 0x03 shl // [(0xff < (x >> r)) << 3, r, x] + or // [r | (0xff < (x >> r)) << 3, x] + + dup2 dup2 // [r, x, r, x] + shr // [x >> r, r, x] + 0x0f lt // [0x0f < (x >> r), r, x] + 0x02 shl // [(0x0f < (x >> r)) << 2, r, x] + or // [r | (0x0f < (x >> r)) << 2, x] + + dup2 dup2 // [r, x, r, x] + shr // [x >> r, r, x] + 0x03 lt // [0x03 < (x >> r), r, x] + 0x01 shl // [(0x03 < (x >> r)) << 1, r, x] + or // [r | (0x03 < (x >> r)) << 1, x] + + dup2 dup2 // [r, x, r, x] + shr // [x >> r, r, x] + 0x01 lt // [0x01 < (x >> r), r, x] + or // [r, x] + swap1 pop // [r] + + // Return stack: // [result] +} + +/// @notice Calculates the cube root of the stack input +/// Credits: https://github.com/Vectorized/solady/blob/main/src/utils/FixedPointMathLib.sol#L504 +#define macro CBRT() = takes (1) returns (1) { + // Input Stack: [x] + + // r construction + + dup1 // [x, x] + 0xffffffffffffffffffffffffffffffff // [0xffffffffffffffffffffffffffffffff, x, x] + lt // [0xffffffffffffffffffffffffffffffff< x, x] + 0x7 shl // [0xffffffffffffffffffffffffffffffff < x << 7, x] + // r = 0xffffffffffffffffffffffffffffffff < x << 7 + + dup2 dup2 // [r, x, r, x] + shr // [x >> r, r, x] + 0xffffffffffffffff // [0xffffffffffffffff, x >> r, r, x] + lt // [0xffffffffffffffff < x >> r, r, x] + 0x6 shl // [0xffffffffffffffff < x >> r << 6, r, x] + or // [0xffffffffffffffff < x >> r << 6 | r, x] + // r' = r | (0xffffffffffffffff < (x >> r)) << 6 + + dup2 dup2 // [r', x, r', x] + shr // [x >> r', r', x] + 0xffffffff // [0xffffffff, x >> r', r', x] + lt // [0xffffffff < x >> r, r', x] + 0x5 shl // [0xffffffff < x >> r << 5, r', x] + or // [0xffffffff < x >> r << 5 | r', x] + // r' = r' | 0xffffffff < x >> r << 5 + + dup2 dup2 // [r', x, r', x] + shr // [x >> r', r', x] + 0xffff // [0xffff, x >> r', r',x] + lt // [0xffff < x >> r', r', x] + 0x4 shl // [0xffff < x >> r' << 4, r', x] + or // [0xffff < x >> r' << 4 | r', x] + // r' = r' | 0xffff < x >> r' << 4 + + dup2 dup2 // [r', x, r', x] + shr // [x >> r', r', x] + 0xff // [0xff, x >> r', r', x] + lt // [0xff < x >> r', r', x] + 0x3 shl // [0xff < x >> r' << 3, r', x] + or // [0xff < x >> r' << 3 | r', x] + // r' = r'|0xff < x >> r' << 3 + + // z construction + + 0xff // [0xff, r', x] + dup3 dup3 // [r', x, 0xff, r', x] + shr // [x >> r', 0xff, r', x] + 0xf // [0xf, x >> r', 0xff, r', x] + lt // [0xf < x >> r', 0xff, r', x] + 0x3 // [3, 0xf < x >> r', 0xff, r', x] + dup4 // [r', 3, 0xf < x >> r', 0xff, r', x] + div // [r' / 3, 0xf < x >> r', 0xff, r', x] + add // [r' / 3 + 0xf < x >> r', 0xff, r', x] + shl // [0xff << r' / 3 + 0xf < x >> r', r', x] + // z = 0xff << r' / 3 + 0xf < x >> r' + + 0x3 // [0x3, z, r', x] + swap1 // [z, 0x3, r', x] + swap2 // [r', 0x3, z, x] + mod // [r' % 3, z, x] + 0x7f624b // [0x7f624b, r' % 3, z, x] + 0xe8 // [0xe8, 0x7f624b, r' % 3, z, x] + shl // [0x7f624b << 0xe8, r' % 3, z, x] + swap1 // [r' % 3, 0x7f624b << 0xe8, z, x] + byte // [byte(r' % 3, 0x7f624b << 0xe8), z, x] + swap1 // [z, byte(r' % 3, 0x7f624b << 0xe8), x] + div // [z / byte(r' % 3, 0x7f624b << 0xe8), x] + // z' = z / byte(r' % 3, 0xe8 << 0x7f624b) + + // Round 1 / 7 + 0x3 // [3, z', x] + swap1 dup1 // [z', z', 3, x] + dup1 dup1 // [z', z', z', z', 3, x] + mul // [z' * z', z', z', 3, x] + dup5 // [x, z' * z', z', z', 3, x] + div add // [x / z' * z' + z', z', 3, x] + add div // [((x / (z' * z')) + z') + z') / 3, x] + // z' = ((x / (z' * z'))+ z') + z') / 3 + + // Round 2 / 7 + 0x3 // [3, z', x] + swap1 dup1 // [z', z', 3, x] + dup1 dup1 // [z', z', z', z', 3, x] + mul // [z' * z', z', z', 3, x] + dup5 // [x, z' * z', z', z', 3, x] + div add // [x / z' * z' + z', z', 3, x] + add div // [((x / (z' * z'))+ z') + z') / 3, x] + // z' = ((x / (z' * z'))+ z') + z') / 3 + + // Round 3 / 7 + 0x3 // [3, z', x] + swap1 dup1 // [z', z', 3, x] + dup1 dup1 // [z', z', z', z', 3, x] + mul // [z' * z', z', z', 3, x] + dup5 // [x, z' * z', z', z', 3, x] + div add // [x / z' * z' + z', z', 3, x] + add div // [((x / (z' * z'))+ z') + z') / 3, x] + // z' = ((x / (z' * z'))+ z') + z') / 3 + + // Round 4 / 7 + 0x3 // [3, z', x] + swap1 dup1 // [z', z', 3, x] + dup1 dup1 // [z', z', z', z', 3, x] + mul // [z' * z', z', z', 3, x] + dup5 // [x, z' * z', z', z', 3, x] + div add // [x / z' * z' + z', z', 3, x] + add div // [((x / (z' * z'))+ z') + z') / 3, x] + // z' = ((x / (z' * z'))+ z') + z') / 3 + + // Round 5 / 7 + 0x3 // [3, z', x] + swap1 dup1 // [z', z', 3, x] + dup1 dup1 // [z', z', z', z', 3, x] + mul // [z' * z', z', z', 3, x] + dup5 // [x, z' * z', z', z', 3, x] + div add // [x / z' * z' + z', z', 3, x] + add div // [((x / (z' * z'))+ z') + z') / 3, x] + // z' = ((x / (z' * z'))+ z') + z') / 3 + + // Round 6 / 7 + 0x3 // [3, z', x] + swap1 dup1 // [z', z', 3, x] + dup1 dup1 // [z', z', z', z', 3, x] + mul // [z' * z', z', z', 3, x] + dup5 // [x, z' * z', z', z', 3, x] + div add // [x / z' * z' + z', z', 3, x] + add div // [((x / (z' * z'))+ z') + z') / 3, x] + // z' = ((x / (z' * z'))+ z') + z') / 3 + + // Round 7 / 7 + 0x3 // [3, z', x] + swap1 dup1 // [z', z', 3, x] + dup1 dup1 // [z', z', z', z', 3, x] + mul // [z' * z', z', z', 3, x] + dup5 // [x, z' * z', z', z', 3, x] + div add // [x / z' * z' + z', z', 3, x] + add div // [((x / (z' * z'))+ z') + z') / 3, x] + // z' = ((x / (z' * z'))+ z') + z') / 3 + + // Final operation + dup1 swap2 // [x, z', z'] + dup2 dup1 // [z', z', x, z', z'] + mul // [z' * z', x, z', z'] + swap1 // [x, z' * z', z', z'] + div // [x / (z' * z'), z', z'] + lt // [x / (z' * z') < z', z'] + swap1 sub // [z' - (x / (z' * z') < z')] + + // Return stack: [result: z'] +} + +//////////////////////////////////////////////////////////////// +// HELPER MACROS // +//////////////////////////////////////////////////////////////// + +#define macro ARRANGE_STACK_MULWAD() = takes (3) returns (3) { + // Input stack: [WAD, x, y] + swap2 // [y, x, WAD] + swap1 // [x, y, WAD] +} + +#define macro ARRANGE_STACK_DIVWAD() = takes (3) returns (3) { + // Input stack: [WAD, x, y] + swap1 // [x, WAD, y] +} + +// TESTS + +#define macro TEST_ASSERT_EQ() = { + eq continue jumpi + 0x00 dup1 revert + continue: +} + +// test wad mul for positive numbers +#define test TEST_WAD_DIV() = { + 0xDE0B6B3A7640000 // [y (1e18)] + 0x1BC16D674EC80000 // [x (2e18),y] + WAD_MUL(fail) // result + 0x1BC16D674EC80000 + TEST_ASSERT_EQ() + continue jump + + fail: + FAIL() + continue: +} + +// test wad mul for positive numbers +#define test TEST_WAD_MUL() = { + 0x0DE0B6B3A7640000 // [y (1e18)] + 0x1BC16D674EC80000 // [x (2e18), y] + WAD_MUL(fail) // result + + 0x1BC16D674EC80000 + TEST_ASSERT_EQ() + continue jump + // catch jump label + fail: + 0x00 dup1 revert + continue: +} + +#define test FAIL_WAD_MUL() = { + 0xF0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + 0x20 + WAD_MUL(fail) + 0x00 dup1 revert + + // succeed if fails + fail: +} + +#define test FAIL_WAD_DIV() = { + 0x00 + 0x0DE0B6B3A7640000 + WAD_DIV(fail) + 0x00 dup1 revert + + // succeed if fails + fail: +} + + +#define test TEST_TO_WAD_UNSAFE() = { + // Test 0x2 * WAD = 2e18 + 0x02 + TO_WAD_UNSAFE() + 0x1BC16D674EC80000 // [2*e18] + TEST_ASSERT_EQ() +} diff --git a/src/math/__TEMP__qvmazraiuhrdvuoecpapxakdrzpwpmuqMath.huff b/src/math/__TEMP__qvmazraiuhrdvuoecpapxakdrzpwpmuqMath.huff new file mode 100644 index 00000000..1c65a83e --- /dev/null +++ b/src/math/__TEMP__qvmazraiuhrdvuoecpapxakdrzpwpmuqMath.huff @@ -0,0 +1,319 @@ + +#define macro SQRT_WRAPPER() = { + 0x04 calldataload + SQRT() + 0x00 mstore + 0x20 0x00 return +} + +#define macro MAX_WRAPPER() = { + 0x04 calldataload + 0x24 calldataload + MAX() + 0x00 mstore + 0x20 0x00 return +} + +#define macro MIN_WRAPPER() = { + 0x04 calldataload + 0x24 calldataload + MIN() + 0x00 mstore + 0x20 0x00 return +} + +#define macro AVG_WRAPPER() = { + 0x04 calldataload + 0x24 calldataload + AVG() + 0x00 mstore + 0x20 0x00 return +} + +#define macro CEIL_DIV_WRAPPER() = { + 0x24 calldataload + 0x04 calldataload + CEIL_DIV() + 0x00 mstore + 0x20 0x00 return +} + +#define macro MAIN() = { + 0x00 calldataload 0xE0 shr + dup1 __FUNC_SIG(sqrt) eq sqrt jumpi + dup1 __FUNC_SIG(max) eq max jumpi + dup1 __FUNC_SIG(min) eq min jumpi + dup1 __FUNC_SIG(average) eq average jumpi + dup1 __FUNC_SIG(ceilDiv) eq ceilDiv jumpi + + 0x00 0x00 revert + + sqrt: + SQRT_WRAPPER() + max: + MAX_WRAPPER() + min: + MIN_WRAPPER() + average: + AVG_WRAPPER() + ceilDiv: + CEIL_DIV_WRAPPER() +} + + +/// @title Math +/// @notice SPDX-License-Identifier: MIT +/// @author manas +/// @author kadenzipfel +/// @notice Math module over Solidity's arithmetic operations +/// @notice Adapted from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/math/Math.sol) + +#include "../utils/Errors.huff" + +// Interface +#define function sqrt(uint256) pure returns(uint256) +#define function max(uint256, uint256) pure returns(uint256) +#define function min(uint256, uint256) pure returns(uint256) +#define function average(uint256, uint256) pure returns(uint256) +#define function ceilDiv(uint256, uint256) pure returns(uint256) + +// Negative 1 in two's compliment +#define constant NEG1 = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + +/// @notice Calculates the square root of a stack input +#define macro SQRT() = takes (1) returns (1) { + // input stack // [num] + // if num == 0 return 0 + dup1 // [number, number] + iszero // [is_zero, number] + is_zero jumpi + + // assign stack vars + dup1 // [x, num] + 0x01 // [result, x, num] + + // if (x >> 128 > 0) { + // x >>= 128; + // result <<= 64; + // } + dup2 // [x, result, x, num] + 0x80 shr // [x >> 128, result, x, num] + dup1 // [x >> 128, x >> 128, result, x, num] + iszero // [x >> 128 == 0, x >> 128, result, x, num] + sh_128_0 jumpi + swap1 0x40 shl // [result, x >> 128, x, num] + swap1 swap2 // [x, result, x >> 128, num] + sh_128_0: + pop + + // if (x >> 64 > 0) { + // x >>= 64; + // result <<= 32; + // } + dup2 // [x, result, x, num] + 0x40 shr // [x >> 64, result, x, num] + dup1 // [x >> 64, x >> 64, result, x, num] + iszero // [x >> 64 == 0, x >> 64, result, x, num] + sh_64_0 jumpi + swap1 0x20 shl // [result, x >> 64, x, num] + swap1 swap2 // [x, result, x >> 64, num] + sh_64_0: + pop + + // if (x >> 32 > 0) { + // x >>= 32; + // result <<= 16; + // } + dup2 // [x, result, x, num] + 0x20 shr // [x >> 32, result, x, num] + dup1 // [x >> 32, x >> 32, result, x, num] + iszero // [x >> 32 == 0, x >> 32, result, x, num] + sh_32_0 jumpi + swap1 0x10 shl // [result, x >> 32, x, num] + swap1 swap2 // [x, result, x >> 32, num] + sh_32_0: + pop + + // if (x >> 16 > 0) { + // x >>= 16; + // result <<= 8; + // } + dup2 // [x, result, x, num] + 0x10 shr // [x >> 16, result, x, num] + dup1 // [x >> 16, x >> 16, result, x, num] + iszero // [x >> 16 == 0, x >> 16, result, x, num] + sh_16_0 jumpi + swap1 0x08 shl // [result, x >> 16, x, num] + swap1 swap2 // [x, result, x >> 16, num] + sh_16_0: + pop + + // if (x >> 8 > 0) { + // x >>= 8; + // result <<= 4; + // } + dup2 // [x, result, x, num] + 0x08 shr // [x >> 8, result, x, num] + dup1 // [x >> 8, x >> 8, result, x, num] + iszero // [x >> 8 == 0, x >> 8, result, x, num] + sh_8_0 jumpi + swap1 0x04 shl // [result, x >> 8, x, num] + swap1 swap2 // [x, result, x >> 8, num] + sh_8_0: + pop + + // if (x >> 4 > 0) { + // x >>= 4; + // result <<= 2; + // } + dup2 // [x, result, x, num] + 0x04 shr // [x >> 4, result, x, num] + dup1 // [x >> 4, x >> 4, result, x, num] + iszero // [x >> 4 == 0, x >> 4, result, x, num] + sh_4_0 jumpi + swap1 0x02 shl // [result, x >> 4, x, num] + swap1 swap2 // [x, result, x >> 4, num] + sh_4_0: + pop + + // if (x >> 2 > 0) { + // x >>= 2; + // result <<= 1; + // } + dup2 // [x, result, x, num] + 0x02 shr // [x >> 2, result, x, num] + dup1 // [x >> 2, x >> 2, result, x, num] + iszero // [x >> 2 == 0, x >> 2, result, x, num] + sh_2_0 jumpi + swap1 0x01 shl // [result, x >> 2, x, num] + swap1 swap2 // [x, result, x >> 2, num] + sh_2_0: + pop + + // result = (result + num / result) >> 1; + dup1 // [result, result, x, num] + dup4 // [num, result, result, x, num] + div // [num / result, result x, num] + add // [result + num / result, x, num] + 0x01 shr // [result, x, num] + + // result = (result + num / result) >> 1; + dup1 // [result, result, x, num] + dup4 // [num, result, result, x, num] + div // [num / result, result, x, num] + add // [result + num / result, x, num] + 0x01 shr // [result, x, num] + + // result = (result + num / result) >> 1; + dup1 // [result, result, x, num] + dup4 // [num, result, result, x, num] + div // [num / result, result, x, num] + add // [result + num / result, x, num] + 0x01 shr // [result, x, num] + + // result = (result + num / result) >> 1; + dup1 // [result, result, x, num] + dup4 // [num, result, result, x, num] + div // [num / result, result, x, num] + add // [result + num / result, x, num] + 0x01 shr // [result, x, num] + + // result = (result + num / result) >> 1; + dup1 // [result, result, x, num] + dup4 // [num, result, result, x, num] + div // [num / result, result, x, num] + add // [result + num / result, x, num] + 0x01 shr // [result, x, num] + + // result = (result + num / result) >> 1; + dup1 // [result, result, x, num] + dup4 // [num, result, result, x, num] + div // [num / result, result, x, num] + add // [result + num / result, x, num] + 0x01 shr // [result, x, num] + + // result = (result + num / result) >> 1; + dup1 // [result, result, x, num] + dup4 // [num, result, result, x, num] + div // [num / result, result, x, num] + add // [result + num / result, x, num] + 0x01 shr // [result, x, num] + + // result = min(result, num / result) + dup1 // [result, result, x, num] + swap3 // [num, result, x, result] + div // [num / result, x, result] + swap2 swap1 pop // [result, num / result] + MIN() + + is_zero: +} + +/// @notice Returns the maximum value of two values on the stack +#define macro MAX() = takes (2) returns (1) { + // input stack: // [num1, num2] + dup2 // [num2, num1, num2] + dup2 // [num1, num2, num1, num2] + lt // [is_less_than, num1, num2] + + less_than jumpi + swap1 // [num1, num2] + + less_than: + pop // [max(num2, num1)] +} + +/// @notice Returns the ceiling of the division of two values on the stack +#define macro CEIL_DIV() = takes (2) returns (1) { + // input stack: // [num1, num2] + dup1 iszero // [is_zero, num1, num2] + if_zero jumpi + + dup2 iszero // [is_zero, num1, num2] + divide_by_zero jumpi + + 0x01 // [1, num1, num2] + swap1 // [num1, 1, num1] + sub // [num1 - 1, num2] + div 0x01 add // [((num1 - 1) / num2) + 1] + dest jump + + divide_by_zero: + [DIVIDE_BY_ZERO] PANIC() + + if_zero: + swap1 // [num2, num1] + pop // [num1] + + dest: +} + +/// @notice Returns the minimum value of two values on the stack +#define macro MIN() = takes (2) returns (1) { + // input stack: // [num1, num2] + dup2 dup2 gt // [is_greater_than, num1, num2] + + greater_than jumpi + swap1 // [num2, num1] + + greater_than: + pop // [min(num1, num2)] +} + +/// @notice Returns the average of two values on the stack +#define macro AVG() = takes (2) returns (1) { + // input stack: // [num1, num2] + dup2 dup2 and // [num1 & num2, num1, num2] + swap2 // [num2, num1, num1 & num2] + xor // [num2 ^ num1, num1 & num2] + 0x02 swap1 div // [num2 ^ num1 / 2, num1 & num2] + add // [sum] +} + +/// @notice Unsafely subtracts 1 from a uint256 using the 2's complement representation +#define macro UNSAFE_SUB() = takes (1) returns (1) { + // Input Stack: [x] + // Output Stack: [x - 1] + + [NEG1] add // [x - 1] +} \ No newline at end of file diff --git a/src/math/__TEMP__wqcimbuhetstepqivcpdmtxszazlqpnnSafeMath.huff b/src/math/__TEMP__wqcimbuhetstepqivcpdmtxszazlqpnnSafeMath.huff new file mode 100644 index 00000000..8ac2256c --- /dev/null +++ b/src/math/__TEMP__wqcimbuhetstepqivcpdmtxszazlqpnnSafeMath.huff @@ -0,0 +1,153 @@ + +// Wrapper methods (for testing) +#define macro SAFE_ADD_WRAPPER() = takes (0) returns (0) { + 0x04 calldataload // [num1] + 0x24 calldataload // [num2, num1] + SAFE_ADD() // [result] + 0x00 mstore // [] + 0x20 0x00 return // [] +} + +#define macro SAFE_SUB_WRAPPER() = takes (0) returns (0) { + 0x04 calldataload // [num1] + 0x24 calldataload // [num2, num1] + swap1 // [num1, num2] + SAFE_SUB() // [result] + 0x00 mstore // [] + 0x20 0x00 return // [] +} + +#define macro SAFE_MUL_WRAPPER() = takes (0) returns (0) { + 0x04 calldataload // [num1] + 0x24 calldataload // [num2, num1] + SAFE_MUL() // [result] + 0x00 mstore // [] + 0x20 0x00 return // [] +} + +#define macro SAFE_DIV_WRAPPER() = takes (0) returns (0) { + 0x04 calldataload // [num1] + 0x24 calldataload // [num2, num1] + swap1 // [num1, num2] + SAFE_DIV() // [result] + 0x00 mstore // [] + 0x20 0x00 return // [] +} + +#define macro SAFE_MOD_WRAPPER() = takes (0) returns (0) { + 0x04 calldataload // [num1] + 0x24 calldataload // [num2, num1] + swap1 // [num1, num2] + SAFE_MOD() // [result] + 0x00 mstore // [] + 0x20 0x00 return // [] +} + +// Main +#define macro MAIN() = takes (0) returns (0) { + 0x00 calldataload 0xE0 shr + dup1 __FUNC_SIG(safeAdd) eq safe_add jumpi + dup1 __FUNC_SIG(safeSub) eq safe_sub jumpi + dup1 __FUNC_SIG(safeMul) eq safe_mul jumpi + dup1 __FUNC_SIG(safeDiv) eq safe_div jumpi + dup1 __FUNC_SIG(safeMod) eq safe_mod jumpi + + 0x00 0x00 revert + + safe_add: + SAFE_ADD_WRAPPER() + safe_sub: + SAFE_SUB_WRAPPER() + safe_mul: + SAFE_MUL_WRAPPER() + safe_div: + SAFE_DIV_WRAPPER() + safe_mod: + SAFE_MOD_WRAPPER() +} + +/// @title SafeMath +/// @notice SPDX-License-Identifier: MIT +/// @author kadenzipfel +/// @notice Math module over Solidity's arithmetic operations with safety checks +/// @notice Adapted from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/math/SafeMath.sol) + +#include "../utils/Errors.huff" + +// Interface +#define function safeAdd(uint256,uint256) pure returns (uint256) +#define function safeSub(uint256,uint256) pure returns (uint256) +#define function safeMul(uint256,uint256) pure returns (uint256) +#define function safeDiv(uint256,uint256) pure returns (uint256) +#define function safeMod(uint256,uint256) pure returns (uint256) + +/// @notice Adds two numbers and reverts on overflow +#define macro SAFE_ADD() = takes (2) returns (1) { + // input stack // [num1, num2] + dup2 // [num2, num1, num2] + add // [result, num2] + dup1 // [result, result, num2] + swap2 // [num2, result, result] + gt // [is_overflow, result] + iszero // [is_not_overflow, result] + is_not_overflow jumpi // [result] + [ARITHMETIC_OVERFLOW] PANIC() + is_not_overflow: // [result] +} + +/// @notice Subtracts two numbers and reverts on underflow +#define macro SAFE_SUB() = takes (2) returns (1) { + // input stack // [num1, num2] + dup1 // [num1, num1, num2] + dup3 // [num2, num1, num1, num2] + gt // [is_underflow, num1, num2] + iszero // [is_not_underflow, num1, num2] + is_not_underflow jumpi // [num1, num2] + [ARITHMETIC_OVERFLOW] PANIC() + is_not_underflow: // [num1, num2] + sub // [result] +} + +/// @notice Multiplies two numbers and reverts on overflow +#define macro SAFE_MUL() = takes (2) returns (1) { + // input stack // [num1, num2] + dup1 // [num1, num1, num2] + is_not_zero jumpi // [num1, num2] + mul // [result] + 0x01 is_not_overflow jumpi + is_not_zero: // [num1, num2] + dup2 // [num2, num1, num2] + dup2 // [num1, num2, num1, num2] + mul // [result, num1, num2] + swap1 // [num1, result, num2] + dup2 // [result, num1, result, num2] + div // [div_check, result, num2] + swap1 // [result, div_check, num2] + swap2 // [num2, div_check, result] + eq // [is_not_overflow, result] + is_not_overflow jumpi // [result] + [ARITHMETIC_OVERFLOW] PANIC() + is_not_overflow: +} + +/// @notice Divides two numbers and reverts on division by zero +#define macro SAFE_DIV() = takes (2) returns (1) { + // input stack // [num1, num2] + 0x00 dup3 // [num2, 0, num1, num2] + gt // [is_not_div_zero, num1, num2] + is_not_div_zero jumpi + [DIVIDE_BY_ZERO] PANIC() + is_not_div_zero: + div // [result] +} + +/// @notice Divides two numbers and reverts on division by zero or modulo zero +#define macro SAFE_MOD() = takes (2) returns (1) { + // input stack // [num1, num2] + 0x00 dup3 // [num2, 0, num1, num2] + gt // [is_not_mod_zero, num1, num2] + is_not_mod_zero jumpi + [ARITHMETIC_OVERFLOW] PANIC() + is_not_mod_zero: + mod // [result] +} \ No newline at end of file diff --git a/src/mechanisms/huff-clones/__TEMP__hvlmmbwdwsqmdvneonbcfprxtzfbmhkuExampleClone.huff b/src/mechanisms/huff-clones/__TEMP__hvlmmbwdwsqmdvneonbcfprxtzfbmhkuExampleClone.huff new file mode 100644 index 00000000..5aca4ff7 --- /dev/null +++ b/src/mechanisms/huff-clones/__TEMP__hvlmmbwdwsqmdvneonbcfprxtzfbmhkuExampleClone.huff @@ -0,0 +1,77 @@ + + +/// @title ExampleClone +/// @notice SPDX-License-Identifier: MIT +/// @author wighawag +/// @author zefram +/// @author hari +/// @author z0r0z +/// @author clabby +/// @notice Clones with Immutable Args Library +/// @notice Adapted from wighawag (https://github.com/wighawag/clones-with-immutable-args/blob/master/src/ExampleClone.sol) + +#include "./HuffClone.huff" + +#define function param1() view returns (address) +#define function param2() view returns (uint256) +#define function param3() view returns (uint64) +#define function param4() view returns (uint8) +#define function param5(uint256) view returns (uint256[] memory) + +#define macro PARAM_1() = takes (0) returns (0) { + 0x00 GET_ARG_ADDRESS() // [arg_addr] + 0x00 mstore // [] + 0x20 0x00 return +} + +#define macro PARAM_2() = takes (0) returns (0) { + 0x14 GET_ARG_UINT_256() // [arg_uint] + 0x00 mstore // [] + 0x20 0x00 return +} + +#define macro PARAM_3() = takes (0) returns (0) { + 0x34 GET_ARG_UINT_64() // [arg_uint] + 0x00 mstore // [] + 0x20 0x00 return +} + +#define macro PARAM_4() = takes (0) returns (0) { + 0x3C GET_ARG_UINT_8() // [arg_uint] + 0x00 mstore // [] + 0x20 0x00 return +} + +#define macro PARAM_5() = takes (0) returns (0) { + 0x04 calldataload // [arr_len] + + // Store pointer in word before array + 0x20 0x00 mstore // [arr_len] + + dup1 0x00 // [0x00, arr_len, arr_len] + GET_ARG_UINT_256_ARR(0x20) // [ptr, arr_len] + swap1 // [arr_len, ptr] + 0x05 shl // [arr_len * 0x20, ptr] + 0x40 add // [arr_len * 0x20 + 0x40, ptr] + 0x00 return // [ptr] +} + +#define macro MAIN() = takes (0) returns (0) { + pc calldataload 0xE0 shr + dup1 __FUNC_SIG(param1) eq param1 jumpi + dup1 __FUNC_SIG(param2) eq param2 jumpi + dup1 __FUNC_SIG(param3) eq param3 jumpi + dup1 __FUNC_SIG(param4) eq param4 jumpi + dup1 __FUNC_SIG(param5) eq param5 jumpi + + param1: + PARAM_1() + param2: + PARAM_2() + param3: + PARAM_3() + param4: + PARAM_4() + param5: + PARAM_5() +} diff --git a/src/mechanisms/huff-clones/__TEMP__pgbwefuedeoorfkumjbbbagtfehbslnhExampleClone.huff b/src/mechanisms/huff-clones/__TEMP__pgbwefuedeoorfkumjbbbagtfehbslnhExampleClone.huff new file mode 100644 index 00000000..5aca4ff7 --- /dev/null +++ b/src/mechanisms/huff-clones/__TEMP__pgbwefuedeoorfkumjbbbagtfehbslnhExampleClone.huff @@ -0,0 +1,77 @@ + + +/// @title ExampleClone +/// @notice SPDX-License-Identifier: MIT +/// @author wighawag +/// @author zefram +/// @author hari +/// @author z0r0z +/// @author clabby +/// @notice Clones with Immutable Args Library +/// @notice Adapted from wighawag (https://github.com/wighawag/clones-with-immutable-args/blob/master/src/ExampleClone.sol) + +#include "./HuffClone.huff" + +#define function param1() view returns (address) +#define function param2() view returns (uint256) +#define function param3() view returns (uint64) +#define function param4() view returns (uint8) +#define function param5(uint256) view returns (uint256[] memory) + +#define macro PARAM_1() = takes (0) returns (0) { + 0x00 GET_ARG_ADDRESS() // [arg_addr] + 0x00 mstore // [] + 0x20 0x00 return +} + +#define macro PARAM_2() = takes (0) returns (0) { + 0x14 GET_ARG_UINT_256() // [arg_uint] + 0x00 mstore // [] + 0x20 0x00 return +} + +#define macro PARAM_3() = takes (0) returns (0) { + 0x34 GET_ARG_UINT_64() // [arg_uint] + 0x00 mstore // [] + 0x20 0x00 return +} + +#define macro PARAM_4() = takes (0) returns (0) { + 0x3C GET_ARG_UINT_8() // [arg_uint] + 0x00 mstore // [] + 0x20 0x00 return +} + +#define macro PARAM_5() = takes (0) returns (0) { + 0x04 calldataload // [arr_len] + + // Store pointer in word before array + 0x20 0x00 mstore // [arr_len] + + dup1 0x00 // [0x00, arr_len, arr_len] + GET_ARG_UINT_256_ARR(0x20) // [ptr, arr_len] + swap1 // [arr_len, ptr] + 0x05 shl // [arr_len * 0x20, ptr] + 0x40 add // [arr_len * 0x20 + 0x40, ptr] + 0x00 return // [ptr] +} + +#define macro MAIN() = takes (0) returns (0) { + pc calldataload 0xE0 shr + dup1 __FUNC_SIG(param1) eq param1 jumpi + dup1 __FUNC_SIG(param2) eq param2 jumpi + dup1 __FUNC_SIG(param3) eq param3 jumpi + dup1 __FUNC_SIG(param4) eq param4 jumpi + dup1 __FUNC_SIG(param5) eq param5 jumpi + + param1: + PARAM_1() + param2: + PARAM_2() + param3: + PARAM_3() + param4: + PARAM_4() + param5: + PARAM_5() +} diff --git a/src/mechanisms/huff-clones/__TEMP__xhkqnmmjajsmfrshnyoafedbhvmybxcfExampleClone.huff b/src/mechanisms/huff-clones/__TEMP__xhkqnmmjajsmfrshnyoafedbhvmybxcfExampleClone.huff new file mode 100644 index 00000000..5aca4ff7 --- /dev/null +++ b/src/mechanisms/huff-clones/__TEMP__xhkqnmmjajsmfrshnyoafedbhvmybxcfExampleClone.huff @@ -0,0 +1,77 @@ + + +/// @title ExampleClone +/// @notice SPDX-License-Identifier: MIT +/// @author wighawag +/// @author zefram +/// @author hari +/// @author z0r0z +/// @author clabby +/// @notice Clones with Immutable Args Library +/// @notice Adapted from wighawag (https://github.com/wighawag/clones-with-immutable-args/blob/master/src/ExampleClone.sol) + +#include "./HuffClone.huff" + +#define function param1() view returns (address) +#define function param2() view returns (uint256) +#define function param3() view returns (uint64) +#define function param4() view returns (uint8) +#define function param5(uint256) view returns (uint256[] memory) + +#define macro PARAM_1() = takes (0) returns (0) { + 0x00 GET_ARG_ADDRESS() // [arg_addr] + 0x00 mstore // [] + 0x20 0x00 return +} + +#define macro PARAM_2() = takes (0) returns (0) { + 0x14 GET_ARG_UINT_256() // [arg_uint] + 0x00 mstore // [] + 0x20 0x00 return +} + +#define macro PARAM_3() = takes (0) returns (0) { + 0x34 GET_ARG_UINT_64() // [arg_uint] + 0x00 mstore // [] + 0x20 0x00 return +} + +#define macro PARAM_4() = takes (0) returns (0) { + 0x3C GET_ARG_UINT_8() // [arg_uint] + 0x00 mstore // [] + 0x20 0x00 return +} + +#define macro PARAM_5() = takes (0) returns (0) { + 0x04 calldataload // [arr_len] + + // Store pointer in word before array + 0x20 0x00 mstore // [arr_len] + + dup1 0x00 // [0x00, arr_len, arr_len] + GET_ARG_UINT_256_ARR(0x20) // [ptr, arr_len] + swap1 // [arr_len, ptr] + 0x05 shl // [arr_len * 0x20, ptr] + 0x40 add // [arr_len * 0x20 + 0x40, ptr] + 0x00 return // [ptr] +} + +#define macro MAIN() = takes (0) returns (0) { + pc calldataload 0xE0 shr + dup1 __FUNC_SIG(param1) eq param1 jumpi + dup1 __FUNC_SIG(param2) eq param2 jumpi + dup1 __FUNC_SIG(param3) eq param3 jumpi + dup1 __FUNC_SIG(param4) eq param4 jumpi + dup1 __FUNC_SIG(param5) eq param5 jumpi + + param1: + PARAM_1() + param2: + PARAM_2() + param3: + PARAM_3() + param4: + PARAM_4() + param5: + PARAM_5() +} diff --git a/src/mechanisms/huff-clones/__TEMP__xpmxrssqgllfjrqfvrmjmhzvpeefnmpcExampleClone.huff b/src/mechanisms/huff-clones/__TEMP__xpmxrssqgllfjrqfvrmjmhzvpeefnmpcExampleClone.huff new file mode 100644 index 00000000..5aca4ff7 --- /dev/null +++ b/src/mechanisms/huff-clones/__TEMP__xpmxrssqgllfjrqfvrmjmhzvpeefnmpcExampleClone.huff @@ -0,0 +1,77 @@ + + +/// @title ExampleClone +/// @notice SPDX-License-Identifier: MIT +/// @author wighawag +/// @author zefram +/// @author hari +/// @author z0r0z +/// @author clabby +/// @notice Clones with Immutable Args Library +/// @notice Adapted from wighawag (https://github.com/wighawag/clones-with-immutable-args/blob/master/src/ExampleClone.sol) + +#include "./HuffClone.huff" + +#define function param1() view returns (address) +#define function param2() view returns (uint256) +#define function param3() view returns (uint64) +#define function param4() view returns (uint8) +#define function param5(uint256) view returns (uint256[] memory) + +#define macro PARAM_1() = takes (0) returns (0) { + 0x00 GET_ARG_ADDRESS() // [arg_addr] + 0x00 mstore // [] + 0x20 0x00 return +} + +#define macro PARAM_2() = takes (0) returns (0) { + 0x14 GET_ARG_UINT_256() // [arg_uint] + 0x00 mstore // [] + 0x20 0x00 return +} + +#define macro PARAM_3() = takes (0) returns (0) { + 0x34 GET_ARG_UINT_64() // [arg_uint] + 0x00 mstore // [] + 0x20 0x00 return +} + +#define macro PARAM_4() = takes (0) returns (0) { + 0x3C GET_ARG_UINT_8() // [arg_uint] + 0x00 mstore // [] + 0x20 0x00 return +} + +#define macro PARAM_5() = takes (0) returns (0) { + 0x04 calldataload // [arr_len] + + // Store pointer in word before array + 0x20 0x00 mstore // [arr_len] + + dup1 0x00 // [0x00, arr_len, arr_len] + GET_ARG_UINT_256_ARR(0x20) // [ptr, arr_len] + swap1 // [arr_len, ptr] + 0x05 shl // [arr_len * 0x20, ptr] + 0x40 add // [arr_len * 0x20 + 0x40, ptr] + 0x00 return // [ptr] +} + +#define macro MAIN() = takes (0) returns (0) { + pc calldataload 0xE0 shr + dup1 __FUNC_SIG(param1) eq param1 jumpi + dup1 __FUNC_SIG(param2) eq param2 jumpi + dup1 __FUNC_SIG(param3) eq param3 jumpi + dup1 __FUNC_SIG(param4) eq param4 jumpi + dup1 __FUNC_SIG(param5) eq param5 jumpi + + param1: + PARAM_1() + param2: + PARAM_2() + param3: + PARAM_3() + param4: + PARAM_4() + param5: + PARAM_5() +} diff --git a/src/mechanisms/huff-vrgda/__TEMP__emehkakqdlyztnvsbkuhzfucpimehhtdLogisticVRGDA.huff b/src/mechanisms/huff-vrgda/__TEMP__emehkakqdlyztnvsbkuhzfucpimehhtdLogisticVRGDA.huff new file mode 100644 index 00000000..61963e7c --- /dev/null +++ b/src/mechanisms/huff-vrgda/__TEMP__emehkakqdlyztnvsbkuhzfucpimehhtdLogisticVRGDA.huff @@ -0,0 +1,77 @@ + +#define function getTargetSaleTime(int256) view returns (int256) +#define function getVRGDAPrice(int256, uint256) view returns (uint256) + +// Getters to demonstrate how to override constants in huff +#define function targetPrice() view returns(int256) +#define function decayConstant() view returns(int256) +#define function timeScale() view returns(int256) +#define function logisticLimit() view returns(int256) +#define function logisticLimitDoubled() view returns(int256) + + +#define macro MAIN() = { + pc calldataload 0xE0 shr + dup1 __FUNC_SIG(getVRGDAPrice) eq getVRGDAPrice jumpi + dup1 __FUNC_SIG(getTargetSaleTime) eq getTargetSaleTime jumpi + dup1 __FUNC_SIG(targetPrice) eq targetPrice jumpi + dup1 __FUNC_SIG(decayConstant) eq decayConstant jumpi + dup1 __FUNC_SIG(timeScale) eq timeScale jumpi + dup1 __FUNC_SIG(logisticLimit) eq logisticLimit jumpi + dup1 __FUNC_SIG(logisticLimitDoubled) eq logisticLimitDoubled jumpi + + fail: + 0x00 dup1 revert + + getVRGDAPrice: + GET_VRGDA_PRICE_EXTERNAL(fail) + getTargetSaleTime: + GET_TARGET_SALE_TIME_EXTERNAL(fail) + targetPrice: + RETURN_CONSTANT(TARGET_PRICE) + decayConstant: + RETURN_CONSTANT(DECAY_CONSTANT) + timeScale: + RETURN_CONSTANT(TIME_SCALE) + logisticLimit: + RETURN_CONSTANT(LOGISTIC_LIMIT) + logisticLimitDoubled: + RETURN_CONSTANT(LOGISTIC_LIMIT_DOUBLED) +} + + +/// @title Logistic Variable Rate Gradual Dutch Auction +/// @notice SPDX-License-Identifier: MIT +/// @author transmissions11 +/// @author FrankieIsLost +/// @author Maddiaa +/// @notice VRGDA with a logistic issuance curve. +/// @notice Original Implementation by Maddiaa (https://github.com/cheethas/huff-vrgda/blob/main/src/LogisticVRGDA.huff) + +#include "./VRGDA.huff" + +#define constant LOGISTIC_LIMIT = 0x00 // ( int256 ) +#define constant LOGISTIC_LIMIT_DOUBLED = 0x00 // ( int256 ) +#define constant TIME_SCALE = 0x00 // ( int256 ) + +/// @dev Given a number of tokens sold, return the target time that number of tokens should be sold by. +/// @param {Stack} sold A number of tokens sold, scaled by 1e18, to get the corresponding target sale time for. +/// @return The target time the tokens should be sold by, scaled by 1e18, where the time is +/// relative, such that 0 means the tokens should be sold immediately when the VRGDA begins. +#define macro GET_TARGET_SALE_TIME(fail) = takes (1) returns (0) { + // init state = [sold] + [TIME_SCALE] // [timeScale, sold] + swap1 // [sold, perTimeUnit] + + [WAD] // [1e18, sold, timescale] + swap1 // [sold, 1e18, timescale] + [LOGISTIC_LIMIT] // [logisticLimit, sold, 1e18, timeScale] + add // [sold + logisticLimit, 1e18, timeScale] + [LOGISTIC_LIMIT_DOUBLED] // [logisticLimitDoubled, (sold+logisticLimit), 1e18, timeScale] + UNSAFE_WAD_DIV() // [(logisticLimitDoubled / (sold + logisticLimit)), 1e18, timeScale] + sub // [((logisticLimitDoubled / (sold + logisticLimit)) - 1e18), timeScale] + + LN_WAD(fail) // [wadLn((logisticLimitDoubled / (sold + logisticLimit)) - 1e18), timeScale] + UNSAFE_WAD_DIV() // [wadLn((logisticLimitDoubled / (sold + logisticLimit)) - 1e18) / timeScale] + 0x00 sub // [-wadLn((logisticLimitDoubled / (sold + logisticLimit)) - 1e18) / timeScale] +} diff --git a/src/mechanisms/huff-vrgda/__TEMP__fldyysnwnrmtgswdmaharirrkhhznvgtLinearVRGDA.huff b/src/mechanisms/huff-vrgda/__TEMP__fldyysnwnrmtgswdmaharirrkhhznvgtLinearVRGDA.huff new file mode 100644 index 00000000..dfa3ff88 --- /dev/null +++ b/src/mechanisms/huff-vrgda/__TEMP__fldyysnwnrmtgswdmaharirrkhhznvgtLinearVRGDA.huff @@ -0,0 +1,57 @@ + +#define function getTargetSaleTime(int256) view returns (int256) +#define function getVRGDAPrice(int256, uint256) view returns (uint256) +#define function targetPrice() view returns (int256) +#define function decayConstant() view returns (int256) +#define function perTimeUnit() view returns (int256) + + +#define macro MAIN() = { + 0x00 calldataload 0xE0 shr + dup1 __FUNC_SIG(getVRGDAPrice) eq getVRGDAPrice jumpi + dup1 __FUNC_SIG(getTargetSaleTime) eq getTargetSaleTime jumpi + dup1 __FUNC_SIG(targetPrice) eq targetPrice jumpi + dup1 __FUNC_SIG(decayConstant) eq decayConstant jumpi + dup1 __FUNC_SIG(perTimeUnit) eq perTimeUnit jumpi + + fail: + 0x00 dup1 revert + + getVRGDAPrice: + GET_VRGDA_PRICE_EXTERNAL(fail) + getTargetSaleTime: + GET_TARGET_SALE_TIME_EXTERNAL(fail) + targetPrice: + RETURN_CONSTANT(TARGET_PRICE) + decayConstant: + RETURN_CONSTANT(DECAY_CONSTANT) + perTimeUnit: + RETURN_CONSTANT(PER_TIME_UNIT) +} + + +/// @title Linear Variable Rate Gradual Dutch Auction +/// @notice SPDX-License-Identifier: MIT +/// @author transmissions11 +/// @author FrankieIsLost +/// @author Maddiaa +/// @notice VRGDA with a linear issuance curve. +/// @notice Original Implementation by Maddiaa (https://github.com/cheethas/huff-vrgda/blob/main/src/LinearVRGDA.huff) + +#include "./VRGDA.huff" + +// These will be overriden with the constructor flag +// The constructor logic will need to be copied within deploy scripts +// in order to inline the correct constants +#define constant PER_TIME_UNIT = 0x00 // ( int256 ) + +/// @dev Given a number of tokens sold, return the target time that number of tokens should be sold by. +/// @param {stack} sold A number of tokens sold, scaled by 1e18, to get the corresponding target sale time for. +/// @return The target time the tokens should be sold by, scaled by 1e18, where the time is +/// relative, such that 0 means the tokens should be sold immediately when the VRGDA begins. +#define macro GET_TARGET_SALE_TIME() = takes (1) returns (0) { + // init state = [sold] + [PER_TIME_UNIT] // [perTimeUnit, sold] + swap1 // [sold, perTimeUnit] + UNSAFE_WAD_DIV() // [sold / perTimeUnit] (targetSaleTime) +} diff --git a/src/proxies/__TEMP__flavwmvnufiarmtrrvilwbhnhmfuxofvClones.huff b/src/proxies/__TEMP__flavwmvnufiarmtrrvilwbhnhmfuxofvClones.huff new file mode 100644 index 00000000..cea3c8f3 --- /dev/null +++ b/src/proxies/__TEMP__flavwmvnufiarmtrrvilwbhnhmfuxofvClones.huff @@ -0,0 +1,213 @@ +#define function clone(address) nonpayable returns (address) +#define function cloneDeterministic(address,bytes32) nonpayable returns (address) +#define function predictDeterministicAddress(address,bytes32) view returns (address) +// #define function predictDeterministicAddress(address,bytes32,address) view returns (address) + +#define macro CLONE_WRAPPER() = { + 0x04 calldataload // [implementation] + CLONE() // [address] + 0x00 mstore // [] + 0x20 0x00 return // return address +} + +#define macro CLONE_DETERMINISTIC_WRAPPER() = { + 0x24 calldataload // [salt] + 0x04 calldataload // [implementation, salt] + CLONE_DETERMINISTIC() // [address] + 0x00 mstore // [] + 0x20 0x00 return // return address +} + +#define macro PREDICT_DETERMINISTIC_ADDRESS_WRAPPER() = { + address // [address(this)] + 0x24 calldataload // [salt, address(this)] + 0x04 calldataload // [implementation, salt, address(this)] + PREDICT_DETERMINISTIC_ADDRESS(0x40) // [address] + 0x00 mstore // [] + 0x20 0x00 return // return address +} + +#define macro PREDICT_DETERMINISTIC_ADDRESS_DEPLOYER_WRAPPER() = { + 0x44 calldataload // [deployer] + 0x24 calldataload // [salt, deployer] + 0x04 calldataload // [implementation, salt, deployer] + PREDICT_DETERMINISTIC_ADDRESS(0x40) // [address] + 0x00 mstore // [] + 0x20 0x00 return // return address +} + +#define macro MAIN() = { + pc calldataload 0xe0 shr + + dup1 __FUNC_SIG(clone) eq clone_jump jumpi + dup1 __FUNC_SIG(cloneDeterministic) eq clone_deterministic_jump jumpi + dup1 __FUNC_SIG(predictDeterministicAddress) eq predict_deterministic_address_jump jumpi + dup1 __FUNC_SIG("predictDeterministicAddress(address,bytes32,address)") eq predict_deterministic_address_deployer_jump jumpi + + // Exit is selector does not match + 0x00 dup1 revert + + clone_jump: + CLONE_WRAPPER() + clone_deterministic_jump: + CLONE_DETERMINISTIC_WRAPPER() + predict_deterministic_address_jump: + PREDICT_DETERMINISTIC_ADDRESS_WRAPPER() + predict_deterministic_address_deployer_jump: + PREDICT_DETERMINISTIC_ADDRESS_DEPLOYER_WRAPPER() +} + +/// @title Clones +/// @notice SPDX-License-Identifier: MIT +/// @author Maddiaa +/// @author asnared +/// @notice https://eips.ethereum.org/EIPS/eip-1167[EIP 1167] is a standard for deploying minimal proxy contracts, also known as "clones". +/// @notice To simply and cheaply clone contract functionality in an immutable way, this standard specifies +/// a minimal bytecode implementation that delegates all calls to a known, fixed address. +/// +/// @notice The library includes functions to deploy a proxy using either `create` (traditional deployment) or `create2` +/// (salted deterministic deployment). It also includes functions to predict the addresses of clones deployed using the +/// deterministic method. +/// @notice Adapted from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/proxy/Clones.sol) + +#include "./ERC1967Upgrade.huff" +#include "../utils/CommonErrors.huff" + +// BEFORE ADDRESS +//--------------------------------------------------------------------------------// +// Opcode | Opcode + Arguments | Description | Stack View // +//--------------------------------------------------------------------------------// +// 0x3d | 0x36 | RETURNDATASIZE | 0 // +// 0x60 | 0x602d | PUSH1 0x2d | 0x2d 0 // +// 0x80 | 0x36 | DUP1 | 0x2d 0x2d 0 // +// 0x60 | 0x600a | PUSH1 0x0a | 0x0a 0x2d 0x2d 0 // +// 0x3d | 0x3d | RETURNDATASIZE | 0 0x0a 0x2d 0x2d 0 // +// 0x39 | 0x39 | CODECOPY | 0x2d 0 // +// 0x81 | 0x81 | DUP2 | 0 0x2d 0 // +// 0xf3 | 0xf3 | RETURN | 0 // + +// 0x36 | 0x36 | CALLDATASIZE | size // +// 0x3d | 0x3d | RETURNDATASIZE | 0 size // +// 0x3d | 0x3d | RETURNDATASIZE | 0 0 size // +// 0x37 | 0x37 | CALLDATACOPY | // +// 0x3d | 0x3d | RETURNDATASIZE | 0 // +// 0x3d | 0x3d | RETURNDATASIZE | 0 0 // +// 0x3d | 0x3d | RETURNDATASIZE | 0 0 0 // +// 0x36 | 0x36 | CALLDATASIZE | size 0 0 0 // +// 0x3d | 0x3d | RETURNDATASIZE | 0 size 0 0 0 // +// 0x73 | 0x73 | PUSH20 | addr 0 size 0 0 0 // + +// AFTER ADDRESS +//--------------------------------------------------------------------------------// +// Opcode | Opcode + Arguments | Description | Stack View // +//--------------------------------------------------------------------------------// +// 0x5a | 0x5a | GAS | gas addr 0 size 0 0 0 // +// 0xf4 | 0xf4 | DELEGATECALL | success 0 // +// 0x3d | 0x3d | RETURNDATASIZE | rds success 0 // +// 0x82 | 0x82 | DUP3 | 0 rds success 0 // +// 0x80 | 0x80 | DUP1 | 0 0 rds success 0 // +// 0x3e | 0x3e | RETURNDATACOPY | success 0 // +// 0x90 | 0x90 | SWAP1 | 0 success // +// 0x3d | 0x3d | RETURNDATASIZE | rds 0 success // +// 0x91 | 0x91 | SWAP2 | success rds 0 // +// 0x60 | 0x602b | PUSH1 0x2b | 0x2b success rds 0 // +// 0x57 | 0x57 | JUMPI | Revert if success == 0 // +// 0xfd | 0xfd | REVERT | // +// 0x5b | 0x5b | JUMPDEST | // +// 0xf3 | 0xf3 | RETURN | // +//--------------------------------------------------------------------------------// + +#define constant BYTECODE_BEFORE_ADDRESS = 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000 +#define constant BYTECODE_AFTER_ADDRESS = 0x5af43d82803e903d91602b57fd5bf3 + +/// @notice Clone a contract using `create`. +/// @param {Stack} Implementation - address of the contract to clone. +#define macro CLONE() = takes (1) returns (1) { + CLONE_MACRO(create) +} + +/// @notice Clone a contract to a deterministic address using `create2`. +/// @param {Stack} Implementation - address of the contract to clone. +/// @param {Stack} Salt - The salt to be added to create2. +#define macro CLONE_DETERMINISTIC() = takes (2) returns (1) { + CLONE_MACRO(create2) +} + +/// @dev Can remain inside the scratch space therefore no memory pointer is required +#define macro CLONE_MACRO(deploy_opcode) = takes (2) returns (1) { + // Input Stack: [implementation, salt [optional]] + + // Store the prefix + __RIGHTPAD(0x3d602d80600a3d3981f3363d3d373d3d3d363d73) // [prefix, implementation, salt] + 0x00 mstore // [implementation, salt] + + // Place the implementation at memory byte 20 + 0x60 shl // [rightpad(implementation), salt] + 0x14 mstore // [salt] + + // Add the suffix after the implementation at byte 40 + __RIGHTPAD(0x5af43d82803e903d91602b57fd5bf3) // [suffix, salt] + 0x28 mstore // [salt] + + // Create the contract + 0x37 // [0x37, salt] + 0x00 // [0x00, 0x37, salt] + 0x00 // [0x00, 0x00, 0x37, salt] + // [address] * This will be create | create2 + + // Throw exception if deployment fails + dup1 iszero create_failed jumpi // [address] + continue jump + + create_failed: + DEPLOYMENT_FAILED(0x00) + + continue: +} + + +/// @dev Memory pointer required as this function nukes memory and this is part of a library +#define macro PREDICT_DETERMINISTIC_ADDRESS(ptr) = takes (3) returns (1) { + // Input Stack: [implementation, salt, deployer] + swap1 swap2 swap1 // [implementation, deployer, salt] + + // Store the creation code prefix at memory byte 0 + __RIGHTPAD(0x3d602d80600a3d3981f3363d3d373d3d3d363d73) // [prefix, implementation, deployer, salt] + mstore // [implementation, deployer, salt] + + // Store the implementation address at memory byte 20 + 0x60 shl // [rightpad(implementation), deployer, salt] + 0x14 add // [ptr + 0x14, implementation, deployer, salt] + mstore // [deployer, salt] + + // Store the creation code suffix at memory byte 40 + __RIGHTPAD(0x5af43d82803e903d91602b57fd5bf3ff) // [bytecode_after, deployer, salt] + 0x28 add // [ptr + 0x28, bytecode_after, deployer, salt] + mstore // [deployer, salt] + + // mstore(add(ptr, 0x38), deployer) + 0x60 shl // [rightpad(deployer), salt] + 0x38 add // [ptr + 0x38, deployer, salt] + mstore // [salt] + + // mstore(add(ptr, 0x58), salt) + 0x4c add // [ptr + 0x58, salt] + mstore // [] + + // Hash and then store in memory + 0x37 // [0x37] + // [ptr, 0x37] + sha3 // [hash] + + 0x6c add // [ptr + 0x6c, hash] + mstore // [] + + // Hash the rest of the data + 0x55 // [0x55] + 0x37 add // [ptr + 0x37, 0x55] + sha3 // [hash] + + // Clean the upper 96 bits (12 bytes) of the hash + // The remaining 160 bits (20 bytes) are the address + 0x60 shl 0x60 shr // [clean(hash)] +} \ No newline at end of file diff --git a/src/proxies/__TEMP__klhwbuerlnsihsjssxbghxugniamuyipERC1967Proxy.huff b/src/proxies/__TEMP__klhwbuerlnsihsjssxbghxugniamuyipERC1967Proxy.huff new file mode 100644 index 00000000..63eb9ef3 --- /dev/null +++ b/src/proxies/__TEMP__klhwbuerlnsihsjssxbghxugniamuyipERC1967Proxy.huff @@ -0,0 +1,158 @@ +// Functions +// Implementation +#define function implementation() nonpayable returns (address) +#define function upgradeTo(address) nonpayable returns () +#define function upgradeToAndCall(address,bytes,bool) nonpayable returns () +#define function upgradeToAndCallUUPS(address,bytes,bool) nonpayable returns () + +// Admin +#define function admin() view returns (address) +#define function changeAdmin(address) nonpayable returns () + +// Beacon +#define function beacon() view returns (address) +#define function setBeacon(address) nonpayable returns () +#define function upgradeBeaconAndCall(address,bytes,bool) nonpayable returns () + + +// Implementations +#define macro IMPLEMENTATION_WRAPPER() = { + IMPLEMENTATION() + 0x00 mstore + 0x20 0x00 return +} + +#define macro UPGRADE_TO_WRAPPER() = { + 0x04 calldataload + UPGRADE_TO() + stop +} + +#define macro UPGRADE_TO_AND_CALL_WRAPPER() = { + 0x44 calldataload // [forceCall] + 0x24 calldataload // [data, forceCall] + 0x04 calldataload // [implementation, data, forceCall] + UPGRADE_TO_AND_CALL() + stop +} + +#define macro UPGRADE_TO_AND_CALL_UUPS_WRAPPER() = { + 0x44 calldataload // [forceCall] + 0x24 calldataload // [data, forceCall] + 0x04 calldataload // [implementation, data, forceCall] + UPGRADE_TO_AND_CALL_UUPS() + stop +} + +// Admin +#define macro GET_ADMIN_WRAPPER() = { + GET_ADMIN() + 0x00 mstore + 0x20 0x00 return +} + +#define macro CHANGE_ADMIN_WRAPPER() = { + 0x04 calldataload + CHANGE_ADMIN() + stop +} + + +// Beacon +#define macro GET_BEACON_WRAPPER() = { + GET_BEACON() + 0x00 mstore + 0x20 0x00 return +} + +#define macro SET_BEACON_WRAPPER() = { + 0x04 calldataload + SET_BEACON() + stop +} + +#define macro UPGRADE_BEACON_TO_AND_CALL_WRAPPER() = { + 0x44 calldataload // [forceCall] + 0x24 calldataload // [data, forceCall] + 0x04 calldataload // [implementation, data, forceCall] + UPGRADE_TO_BEACON_AND_CALL() + stop +} + + +// For the sake of this example, the owner will be passed in +#define macro CONSTRUCTOR() = { + // ERC1967_PROXY_CONSTRUCTOR() + + 0x20 + 0x20 codesize sub + 0x00 + codecopy + 0x00 mload + + SET_ADMIN() +} + +#define macro MAIN() = { + pc calldataload 0xe0 shr + + dup1 __FUNC_SIG(implementation) eq implementation jumpi + dup1 __FUNC_SIG(upgradeTo) eq upgradeTo jumpi + dup1 __FUNC_SIG(upgradeToAndCall) eq upgradeToAndCall jumpi + dup1 __FUNC_SIG(upgradeToAndCallUUPS) eq upgradeToAndCallUUPS jumpi + + dup1 __FUNC_SIG(admin) eq getAdmin jumpi + dup1 __FUNC_SIG(changeAdmin) eq changeAdmin jumpi + + dup1 __FUNC_SIG(beacon) eq getBeacon jumpi + dup1 __FUNC_SIG(setBeacon) eq setBeacon jumpi + dup1 __FUNC_SIG(upgradeBeaconAndCall) eq upgradeBeaconAndCall jumpi + + GET_IMPLEMENTATION() // [implementation] + DELEGATE() + + implementation: + IMPLEMENTATION_WRAPPER() + upgradeTo: + UPGRADE_TO_WRAPPER() + upgradeToAndCall: + UPGRADE_TO_AND_CALL_WRAPPER() + upgradeToAndCallUUPS: + UPGRADE_TO_AND_CALL_UUPS_WRAPPER() + + getAdmin: + GET_ADMIN_WRAPPER() + changeAdmin: + CHANGE_ADMIN_WRAPPER() + + getBeacon: + GET_BEACON_WRAPPER() + setBeacon: + SET_BEACON_WRAPPER() + upgradeBeaconAndCall: + UPGRADE_BEACON_TO_AND_CALL_WRAPPER() + +} + +/// @title ERC1967 Proxy +/// @notice SPDX-License-Identifier: MIT +/// @author asnared +/// @notice An upgradeable proxy that uses the ERC1967 storage layout. +/// @notice Adapted from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/proxy/ERC1967/ERC1967Proxy.sol) + +#include "./Proxy.huff" +#include "./ERC1967Upgrade.huff" + +/// @notice An internal constructor that upgrades the proxy to the implementation and calls the implementation +#define macro ERC1967_PROXY_CONSTRUCTOR() = takes (0) returns (0) { + 0x00 // [forceCall] + 0x24 calldataload // [data, forceCall] + 0x04 calldataload // [address, data, forceCall] + UPGRADE_TO_AND_CALL() // [] +} + +/// @notice Returns the current implementation address +/// @notice Overrideable +#define macro IMPLEMENTATION() = takes (0) returns (1) { + GET_IMPLEMENTATION() +} diff --git a/src/proxies/__TEMP__xlwhmiuazdwnqpgoxdvgcsfczvtfymagClones.huff b/src/proxies/__TEMP__xlwhmiuazdwnqpgoxdvgcsfczvtfymagClones.huff new file mode 100644 index 00000000..cea3c8f3 --- /dev/null +++ b/src/proxies/__TEMP__xlwhmiuazdwnqpgoxdvgcsfczvtfymagClones.huff @@ -0,0 +1,213 @@ +#define function clone(address) nonpayable returns (address) +#define function cloneDeterministic(address,bytes32) nonpayable returns (address) +#define function predictDeterministicAddress(address,bytes32) view returns (address) +// #define function predictDeterministicAddress(address,bytes32,address) view returns (address) + +#define macro CLONE_WRAPPER() = { + 0x04 calldataload // [implementation] + CLONE() // [address] + 0x00 mstore // [] + 0x20 0x00 return // return address +} + +#define macro CLONE_DETERMINISTIC_WRAPPER() = { + 0x24 calldataload // [salt] + 0x04 calldataload // [implementation, salt] + CLONE_DETERMINISTIC() // [address] + 0x00 mstore // [] + 0x20 0x00 return // return address +} + +#define macro PREDICT_DETERMINISTIC_ADDRESS_WRAPPER() = { + address // [address(this)] + 0x24 calldataload // [salt, address(this)] + 0x04 calldataload // [implementation, salt, address(this)] + PREDICT_DETERMINISTIC_ADDRESS(0x40) // [address] + 0x00 mstore // [] + 0x20 0x00 return // return address +} + +#define macro PREDICT_DETERMINISTIC_ADDRESS_DEPLOYER_WRAPPER() = { + 0x44 calldataload // [deployer] + 0x24 calldataload // [salt, deployer] + 0x04 calldataload // [implementation, salt, deployer] + PREDICT_DETERMINISTIC_ADDRESS(0x40) // [address] + 0x00 mstore // [] + 0x20 0x00 return // return address +} + +#define macro MAIN() = { + pc calldataload 0xe0 shr + + dup1 __FUNC_SIG(clone) eq clone_jump jumpi + dup1 __FUNC_SIG(cloneDeterministic) eq clone_deterministic_jump jumpi + dup1 __FUNC_SIG(predictDeterministicAddress) eq predict_deterministic_address_jump jumpi + dup1 __FUNC_SIG("predictDeterministicAddress(address,bytes32,address)") eq predict_deterministic_address_deployer_jump jumpi + + // Exit is selector does not match + 0x00 dup1 revert + + clone_jump: + CLONE_WRAPPER() + clone_deterministic_jump: + CLONE_DETERMINISTIC_WRAPPER() + predict_deterministic_address_jump: + PREDICT_DETERMINISTIC_ADDRESS_WRAPPER() + predict_deterministic_address_deployer_jump: + PREDICT_DETERMINISTIC_ADDRESS_DEPLOYER_WRAPPER() +} + +/// @title Clones +/// @notice SPDX-License-Identifier: MIT +/// @author Maddiaa +/// @author asnared +/// @notice https://eips.ethereum.org/EIPS/eip-1167[EIP 1167] is a standard for deploying minimal proxy contracts, also known as "clones". +/// @notice To simply and cheaply clone contract functionality in an immutable way, this standard specifies +/// a minimal bytecode implementation that delegates all calls to a known, fixed address. +/// +/// @notice The library includes functions to deploy a proxy using either `create` (traditional deployment) or `create2` +/// (salted deterministic deployment). It also includes functions to predict the addresses of clones deployed using the +/// deterministic method. +/// @notice Adapted from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/proxy/Clones.sol) + +#include "./ERC1967Upgrade.huff" +#include "../utils/CommonErrors.huff" + +// BEFORE ADDRESS +//--------------------------------------------------------------------------------// +// Opcode | Opcode + Arguments | Description | Stack View // +//--------------------------------------------------------------------------------// +// 0x3d | 0x36 | RETURNDATASIZE | 0 // +// 0x60 | 0x602d | PUSH1 0x2d | 0x2d 0 // +// 0x80 | 0x36 | DUP1 | 0x2d 0x2d 0 // +// 0x60 | 0x600a | PUSH1 0x0a | 0x0a 0x2d 0x2d 0 // +// 0x3d | 0x3d | RETURNDATASIZE | 0 0x0a 0x2d 0x2d 0 // +// 0x39 | 0x39 | CODECOPY | 0x2d 0 // +// 0x81 | 0x81 | DUP2 | 0 0x2d 0 // +// 0xf3 | 0xf3 | RETURN | 0 // + +// 0x36 | 0x36 | CALLDATASIZE | size // +// 0x3d | 0x3d | RETURNDATASIZE | 0 size // +// 0x3d | 0x3d | RETURNDATASIZE | 0 0 size // +// 0x37 | 0x37 | CALLDATACOPY | // +// 0x3d | 0x3d | RETURNDATASIZE | 0 // +// 0x3d | 0x3d | RETURNDATASIZE | 0 0 // +// 0x3d | 0x3d | RETURNDATASIZE | 0 0 0 // +// 0x36 | 0x36 | CALLDATASIZE | size 0 0 0 // +// 0x3d | 0x3d | RETURNDATASIZE | 0 size 0 0 0 // +// 0x73 | 0x73 | PUSH20 | addr 0 size 0 0 0 // + +// AFTER ADDRESS +//--------------------------------------------------------------------------------// +// Opcode | Opcode + Arguments | Description | Stack View // +//--------------------------------------------------------------------------------// +// 0x5a | 0x5a | GAS | gas addr 0 size 0 0 0 // +// 0xf4 | 0xf4 | DELEGATECALL | success 0 // +// 0x3d | 0x3d | RETURNDATASIZE | rds success 0 // +// 0x82 | 0x82 | DUP3 | 0 rds success 0 // +// 0x80 | 0x80 | DUP1 | 0 0 rds success 0 // +// 0x3e | 0x3e | RETURNDATACOPY | success 0 // +// 0x90 | 0x90 | SWAP1 | 0 success // +// 0x3d | 0x3d | RETURNDATASIZE | rds 0 success // +// 0x91 | 0x91 | SWAP2 | success rds 0 // +// 0x60 | 0x602b | PUSH1 0x2b | 0x2b success rds 0 // +// 0x57 | 0x57 | JUMPI | Revert if success == 0 // +// 0xfd | 0xfd | REVERT | // +// 0x5b | 0x5b | JUMPDEST | // +// 0xf3 | 0xf3 | RETURN | // +//--------------------------------------------------------------------------------// + +#define constant BYTECODE_BEFORE_ADDRESS = 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000 +#define constant BYTECODE_AFTER_ADDRESS = 0x5af43d82803e903d91602b57fd5bf3 + +/// @notice Clone a contract using `create`. +/// @param {Stack} Implementation - address of the contract to clone. +#define macro CLONE() = takes (1) returns (1) { + CLONE_MACRO(create) +} + +/// @notice Clone a contract to a deterministic address using `create2`. +/// @param {Stack} Implementation - address of the contract to clone. +/// @param {Stack} Salt - The salt to be added to create2. +#define macro CLONE_DETERMINISTIC() = takes (2) returns (1) { + CLONE_MACRO(create2) +} + +/// @dev Can remain inside the scratch space therefore no memory pointer is required +#define macro CLONE_MACRO(deploy_opcode) = takes (2) returns (1) { + // Input Stack: [implementation, salt [optional]] + + // Store the prefix + __RIGHTPAD(0x3d602d80600a3d3981f3363d3d373d3d3d363d73) // [prefix, implementation, salt] + 0x00 mstore // [implementation, salt] + + // Place the implementation at memory byte 20 + 0x60 shl // [rightpad(implementation), salt] + 0x14 mstore // [salt] + + // Add the suffix after the implementation at byte 40 + __RIGHTPAD(0x5af43d82803e903d91602b57fd5bf3) // [suffix, salt] + 0x28 mstore // [salt] + + // Create the contract + 0x37 // [0x37, salt] + 0x00 // [0x00, 0x37, salt] + 0x00 // [0x00, 0x00, 0x37, salt] + // [address] * This will be create | create2 + + // Throw exception if deployment fails + dup1 iszero create_failed jumpi // [address] + continue jump + + create_failed: + DEPLOYMENT_FAILED(0x00) + + continue: +} + + +/// @dev Memory pointer required as this function nukes memory and this is part of a library +#define macro PREDICT_DETERMINISTIC_ADDRESS(ptr) = takes (3) returns (1) { + // Input Stack: [implementation, salt, deployer] + swap1 swap2 swap1 // [implementation, deployer, salt] + + // Store the creation code prefix at memory byte 0 + __RIGHTPAD(0x3d602d80600a3d3981f3363d3d373d3d3d363d73) // [prefix, implementation, deployer, salt] + mstore // [implementation, deployer, salt] + + // Store the implementation address at memory byte 20 + 0x60 shl // [rightpad(implementation), deployer, salt] + 0x14 add // [ptr + 0x14, implementation, deployer, salt] + mstore // [deployer, salt] + + // Store the creation code suffix at memory byte 40 + __RIGHTPAD(0x5af43d82803e903d91602b57fd5bf3ff) // [bytecode_after, deployer, salt] + 0x28 add // [ptr + 0x28, bytecode_after, deployer, salt] + mstore // [deployer, salt] + + // mstore(add(ptr, 0x38), deployer) + 0x60 shl // [rightpad(deployer), salt] + 0x38 add // [ptr + 0x38, deployer, salt] + mstore // [salt] + + // mstore(add(ptr, 0x58), salt) + 0x4c add // [ptr + 0x58, salt] + mstore // [] + + // Hash and then store in memory + 0x37 // [0x37] + // [ptr, 0x37] + sha3 // [hash] + + 0x6c add // [ptr + 0x6c, hash] + mstore // [] + + // Hash the rest of the data + 0x55 // [0x55] + 0x37 add // [ptr + 0x37, 0x55] + sha3 // [hash] + + // Clean the upper 96 bits (12 bytes) of the hash + // The remaining 160 bits (20 bytes) are the address + 0x60 shl 0x60 shr // [clean(hash)] +} \ No newline at end of file diff --git a/src/proxies/__TEMP__zgifhurblgmhozyfyviczblaggscrgixERC1967Proxy.huff b/src/proxies/__TEMP__zgifhurblgmhozyfyviczblaggscrgixERC1967Proxy.huff new file mode 100644 index 00000000..63eb9ef3 --- /dev/null +++ b/src/proxies/__TEMP__zgifhurblgmhozyfyviczblaggscrgixERC1967Proxy.huff @@ -0,0 +1,158 @@ +// Functions +// Implementation +#define function implementation() nonpayable returns (address) +#define function upgradeTo(address) nonpayable returns () +#define function upgradeToAndCall(address,bytes,bool) nonpayable returns () +#define function upgradeToAndCallUUPS(address,bytes,bool) nonpayable returns () + +// Admin +#define function admin() view returns (address) +#define function changeAdmin(address) nonpayable returns () + +// Beacon +#define function beacon() view returns (address) +#define function setBeacon(address) nonpayable returns () +#define function upgradeBeaconAndCall(address,bytes,bool) nonpayable returns () + + +// Implementations +#define macro IMPLEMENTATION_WRAPPER() = { + IMPLEMENTATION() + 0x00 mstore + 0x20 0x00 return +} + +#define macro UPGRADE_TO_WRAPPER() = { + 0x04 calldataload + UPGRADE_TO() + stop +} + +#define macro UPGRADE_TO_AND_CALL_WRAPPER() = { + 0x44 calldataload // [forceCall] + 0x24 calldataload // [data, forceCall] + 0x04 calldataload // [implementation, data, forceCall] + UPGRADE_TO_AND_CALL() + stop +} + +#define macro UPGRADE_TO_AND_CALL_UUPS_WRAPPER() = { + 0x44 calldataload // [forceCall] + 0x24 calldataload // [data, forceCall] + 0x04 calldataload // [implementation, data, forceCall] + UPGRADE_TO_AND_CALL_UUPS() + stop +} + +// Admin +#define macro GET_ADMIN_WRAPPER() = { + GET_ADMIN() + 0x00 mstore + 0x20 0x00 return +} + +#define macro CHANGE_ADMIN_WRAPPER() = { + 0x04 calldataload + CHANGE_ADMIN() + stop +} + + +// Beacon +#define macro GET_BEACON_WRAPPER() = { + GET_BEACON() + 0x00 mstore + 0x20 0x00 return +} + +#define macro SET_BEACON_WRAPPER() = { + 0x04 calldataload + SET_BEACON() + stop +} + +#define macro UPGRADE_BEACON_TO_AND_CALL_WRAPPER() = { + 0x44 calldataload // [forceCall] + 0x24 calldataload // [data, forceCall] + 0x04 calldataload // [implementation, data, forceCall] + UPGRADE_TO_BEACON_AND_CALL() + stop +} + + +// For the sake of this example, the owner will be passed in +#define macro CONSTRUCTOR() = { + // ERC1967_PROXY_CONSTRUCTOR() + + 0x20 + 0x20 codesize sub + 0x00 + codecopy + 0x00 mload + + SET_ADMIN() +} + +#define macro MAIN() = { + pc calldataload 0xe0 shr + + dup1 __FUNC_SIG(implementation) eq implementation jumpi + dup1 __FUNC_SIG(upgradeTo) eq upgradeTo jumpi + dup1 __FUNC_SIG(upgradeToAndCall) eq upgradeToAndCall jumpi + dup1 __FUNC_SIG(upgradeToAndCallUUPS) eq upgradeToAndCallUUPS jumpi + + dup1 __FUNC_SIG(admin) eq getAdmin jumpi + dup1 __FUNC_SIG(changeAdmin) eq changeAdmin jumpi + + dup1 __FUNC_SIG(beacon) eq getBeacon jumpi + dup1 __FUNC_SIG(setBeacon) eq setBeacon jumpi + dup1 __FUNC_SIG(upgradeBeaconAndCall) eq upgradeBeaconAndCall jumpi + + GET_IMPLEMENTATION() // [implementation] + DELEGATE() + + implementation: + IMPLEMENTATION_WRAPPER() + upgradeTo: + UPGRADE_TO_WRAPPER() + upgradeToAndCall: + UPGRADE_TO_AND_CALL_WRAPPER() + upgradeToAndCallUUPS: + UPGRADE_TO_AND_CALL_UUPS_WRAPPER() + + getAdmin: + GET_ADMIN_WRAPPER() + changeAdmin: + CHANGE_ADMIN_WRAPPER() + + getBeacon: + GET_BEACON_WRAPPER() + setBeacon: + SET_BEACON_WRAPPER() + upgradeBeaconAndCall: + UPGRADE_BEACON_TO_AND_CALL_WRAPPER() + +} + +/// @title ERC1967 Proxy +/// @notice SPDX-License-Identifier: MIT +/// @author asnared +/// @notice An upgradeable proxy that uses the ERC1967 storage layout. +/// @notice Adapted from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/proxy/ERC1967/ERC1967Proxy.sol) + +#include "./Proxy.huff" +#include "./ERC1967Upgrade.huff" + +/// @notice An internal constructor that upgrades the proxy to the implementation and calls the implementation +#define macro ERC1967_PROXY_CONSTRUCTOR() = takes (0) returns (0) { + 0x00 // [forceCall] + 0x24 calldataload // [data, forceCall] + 0x04 calldataload // [address, data, forceCall] + UPGRADE_TO_AND_CALL() // [] +} + +/// @notice Returns the current implementation address +/// @notice Overrideable +#define macro IMPLEMENTATION() = takes (0) returns (1) { + GET_IMPLEMENTATION() +} diff --git a/src/tokens/__TEMP__fztznazwowexesrohcdykwsmvfkclmuyERC20.huff b/src/tokens/__TEMP__fztznazwowexesrohcdykwsmvfkclmuyERC20.huff new file mode 100644 index 00000000..75ecc0af --- /dev/null +++ b/src/tokens/__TEMP__fztznazwowexesrohcdykwsmvfkclmuyERC20.huff @@ -0,0 +1,676 @@ + +#define function mint(address, uint256) nonpayable returns () +#define function burn(address, uint256) nonpayable returns () + +#define macro BURN() = takes (0) returns (0) { + NON_PAYABLE() + // Setup the stack for the burn function. + 0x04 calldataload // [from] + 0x24 calldataload // [value, from] + + // Call ERC20.huff's _BURN macro + _BURN() // [] + + // Stop Execution + stop // [] +} + +#define macro MINT() = takes (0) returns (0) { + NON_PAYABLE() + + // Setup the stack for the mint function. + 0x04 calldataload // [to] + 0x24 calldataload // [value, to] + + // Call ERC20.huff's _MINT macro + _MINT() // [] + + // Stop Execution + stop // [] +} + +#define macro CONSTRUCTOR() = takes (0) returns (0) { + ERC20_CONSTRUCTOR() +} + +#define macro MAIN() = takes (0) returns (0) { + 0x00 calldataload 0xE0 shr // [sig] + + dup1 __FUNC_SIG(mint) eq mint jumpi // [sig] + dup1 __FUNC_SIG(burn) eq burn jumpi // [sig] + + ERC20_MAIN() // [sig] + + // Revert if no selector matches + 0x00 0x00 revert + + mint: + MINT() + burn: + BURN() +} + +/// @title ERC20 +/// @notice SPDX-License-Identifier: MIT +/// @author asnared +/// @author devtooligan +/// @notice Modern and gas efficient ERC20 + EIP-2612 implementation +/// @notice Adapted from Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC20.sol) + +// Imports +#include "../utils/Errors.huff" +#include "../auth/NonPayable.huff" +#include "../data-structures/Hashmap.huff" + +// Interface +#define function allowance(address,address) view returns (uint256) +#define function approve(address,uint256) nonpayable returns () +#define function balanceOf(address) view returns (uint256) +#define function DOMAIN_SEPARATOR() view returns (bytes32) +#define function nonces(address) view returns (uint256) +#define function permit(address,address,uint256,uint256,uint8,bytes32,bytes32) nonpayable returns () +#define function totalSupply() view returns (uint256) +#define function transfer(address,uint256) nonpayable returns () +#define function transferFrom(address,address,uint256) nonpayable returns () + +// Events +#define event Approval(address indexed, address indexed, uint256) +#define event Transfer(address, address, uint256) + +// Metadata +#define function decimals() nonpayable returns (uint8) +#define function name() nonpayable returns (string) +#define function symbol() nonpayable returns (string) + +// ERC20 Storage +#define constant TOTAL_SUPPLY_SLOT = FREE_STORAGE_POINTER() +#define constant BALANCE_SLOT = FREE_STORAGE_POINTER() +#define constant APPROVAL_SLOT = FREE_STORAGE_POINTER() + +// EIP-2612 STORAGE +#define constant INITIAL_CHAIN_ID = FREE_STORAGE_POINTER() +#define constant INITIAL_DOMAIN_SEPARATOR = FREE_STORAGE_POINTER() +#define constant NONCE_SLOT = FREE_STORAGE_POINTER() + +// Immutables offsets +#define constant DECIMALS_OFFSET = 0x0000000000000000000000000000000000000000000000000000000000000020 +#define constant NAME_OFFSET = 0x00000000000000000000000000000000000000000000000000000000000000a0 +#define constant NAME_LENGTH_OFFSET = 0x00000000000000000000000000000000000000000000000000000000000000c0 +#define constant SYMBOL_OFFSET = 0x0000000000000000000000000000000000000000000000000000000000000040 +#define constant SYMBOL_LENGTH_OFFSET = 0x0000000000000000000000000000000000000000000000000000000000000060 + +// PERMIT_TYPEHASH = keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)") +#define constant PERMIT_TYPEHASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9 +#define constant X_1901 = 0x1901000000000000000000000000000000000000000000000000000000000000 + +// Utility Constants +#define constant UINT_256_MAX = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +#define constant ERROR_SIG = 0x08c379a000000000000000000000000000000000000000000000000000000000 +#define constant ZERO_ADDRESS = 0x0000000000000000000000000000000000000000 + +/// @notice Constructor +/// @notice Sets the initial domain separator and chain ID +#define macro ERC20_CONSTRUCTOR() = takes (0) returns (0) { + // Constructor arguments: + // ?, name_size, name, ?, symbol_size, symbol, decimals + + // This constructor will return the runtime bytecode with all the + // constructor arguments concatenated at the end. + + chainid [INITIAL_CHAIN_ID] sstore // [] + COMPUTE_DOMAIN_SEPARATOR() // [DOMAIN SEPARATOR] + [INITIAL_DOMAIN_SEPARATOR] sstore // [] + + // Copy the runtime bytecode with constructor argument concatenated. + 0x67 // [offset] - constructor code size + dup1 // [offset, offset] + codesize // [total_size, offset, offset] + sub // [runtime_size, offset] + dup1 // [runtime_size, runtime_size, offset] + swap2 // [offset, runtime_size, runtime_size] + returndatasize // [return_offset, offset, runtime_size, runtime_size] + codecopy // [runtime_size] + + // Return the runtime bytecode. + returndatasize // [return_offset, runtime_size] + return // [] +} + +/// @notice Retrives an "immutable" from the runtime bytecode. +#define macro _GET_IMMUTABLE(offset_end, free_memory) = takes (0) returns (1) { + 0x20 // [size] + codesize sub // [offset_code, size] + // [offset_memory, offset_code, size] + codecopy // [] + mload // [value] +} + +/// @notice Approve +/// @notice Grants approval to an operator to transfer tokens on behalf of the sender. +#define macro APPROVE() = takes (0) returns (0) { + NON_PAYABLE() // [] + + 0x24 calldataload // [value] + 0x04 calldataload // [to, value] + caller // [from, to, value] + [APPROVAL_SLOT] // [slot, from, to, value] + STORE_ELEMENT_FROM_KEYS_2D(0x00) // [] + + // Emit the Approval event + 0x24 calldataload // [value] + 0x00 mstore // [] + 0x04 calldataload // [to] + caller // [from, to] + __EVENT_HASH(Approval) // [sig, from, to] + 0x20 0x00 // [0, 32, sig, from, to] + log3 // [] + + // Return 01 for true + 0x01 0x00 mstore // [] + 0x20 0x00 return // [] +} + +/// @notice Transfer +/// @notice Non-Payable function that transfers an amount of tokens from the sender to a recipient. +#define macro TRANSFER() = takes (0) returns (0) { + NON_PAYABLE() + + // Setup the stack for the transfer function. + 0x04 calldataload // [to] + caller // [from, to] + 0x24 calldataload // [value, from, to] + + // Update the balances of the sender and recipient. + _TRANSFER_TAKE_FROM() // [value, from, to] + _TRANSFER_GIVE_TO() // [value, from, to] + + // Emit the transfer event. + 0x00 mstore // [from, to] + __EVENT_HASH(Transfer) // [sig, from, to] + 0x20 0x00 // [0, 32, sig, from, to] + log3 // [] + + // Return "1" to represent a succesful transfer. + 0x01 0x00 mstore // [] + 0x20 0x00 return // [] +} + +/// @notice Transfer From +/// @notice Non-Payable function that transfers an amount of tokens from an address to a recipient. +#define macro TRANSFER_FROM() = takes (0) returns (0) { + NON_PAYABLE() // [] + + // Setup the stack for the transfer function. + 0x24 calldataload // [to] + 0x04 calldataload // [from, to] + caller // [msg.sender, from, to] + dup2 // [from, msg.sender, from, to] + [APPROVAL_SLOT] // [slot, from, msg.sender, from, to] + + // Check for max approval + LOAD_ELEMENT_FROM_KEYS_2D(0x00) // [approved, from, to] + dup1 // [approved, approved, from, to] + 0x44 calldataload // [value, approved, approved, from, to] + + // Check isOwner + dup4 // [from, value, approved, approved, from, to] + caller // [msg.sender, from, value, approved, approved, from, to] + eq // [msg.sender == from, value, approved, approved, from, to] + approved1 jumpi // [value, approved, approved, from, to] + + // Check max approval + dup2 // [approved, value, approved, approved, from, to] + [UINT_256_MAX] // [type(uint).max, approved, value, approved, approved, from, to] + eq // [type(uint).max == approved, value, approved, approved, from, to] + approved1 jumpi // [value, approved, approved, from, to] + + // Check has approval + gt // [value > approved, approved, from, to] + insufficientApproval jumpi // [approved, from, to] + + // Adjust approval + 0x44 calldataload // [value, approved, from, to] + swap1 // [approved, value, from, to] + sub // [approved - value => newApprovalValue, from, to] + caller // [msg.sender, newApprovalValue, from, to] + dup3 // [from, msg.sender, newApprovalValue, from, to] + [APPROVAL_SLOT] // [slot, from, msg.sender, newApprovalValue, from, to] + STORE_ELEMENT_FROM_KEYS_2D(0x00) // [from, to] + approved2 jump // [from, to] + + approved1: // [value, approved, approved, from, to] + pop pop pop // [from, to] + + approved2: // [from, to] + 0x44 calldataload // [value, from, to] + + // Update the balances of the sender and recipient. + _TRANSFER_TAKE_FROM() // [value, from, to] + _TRANSFER_GIVE_TO() // [value, from, to] + + // Emit the transfer event. + 0x00 mstore // [from, to] + __EVENT_HASH(Transfer) // [sig, from, to] + 0x20 0x00 // [0, 32, sig, from, to] + log3 // [] + + // Return "1" to represent a succesful transfer. + 0x01 0x00 mstore // [] + 0x20 0x00 return // [] + + insufficientApproval: + 0x00 0x00 revert // [] +} + +/// @notice Transfers an amount of tokens from +#define macro _TRANSFER_TAKE_FROM() = takes (3) returns (3) { + // input stack: [value, from, to] + dup2 [BALANCE_SLOT] LOAD_ELEMENT_FROM_KEYS(0x00) // [balance, value, from, to] // [from, value, from, to] + dup1 // [balance, balance, value, from, to] + dup3 // [value, balance, balance, value, from, to] + gt // [value > balance, balance, value, from, to] + iszero // [value <= balance, balance, value, from, to] + valid jumpi // [balance, value, from, to] + + // Insufficient balance + 0x00 0x00 revert // [] + + // Update the sender's balance. + valid: + dup2 // [value, balance, value, from, to] + swap1 // [balance, value, value, from, to] + sub // [balance - value, value, from, to] + dup3 // [from, balance - value, value, from, to] + [BALANCE_SLOT] STORE_ELEMENT_FROM_KEYS(0x00) // [value, from, to] +} + +/// @notice Transfers an amount of tokens from one address to another. +#define macro _TRANSFER_GIVE_TO() = takes (3) returns (3) { + // input stack: [value, from, to] + dup3 // [to, value, from, to] + dup2 // [value, to, value, from, to] + swap1 // [to, value, value, from, to] + [BALANCE_SLOT] LOAD_ELEMENT_FROM_KEYS(0x00) // [balance, value, value, from, to] + add // [balance + value, value, from, to] + dup4 // [to, balance + value, value, from, to] + [BALANCE_SLOT] STORE_ELEMENT_FROM_KEYS(0x00) // [value, from, to] +} + +/// @notice Approve +/// @notice Approves an address to spend an amount of tokens on the caller's behalf +#define macro APPROVE() = takes (0) returns (0) { + 0x24 calldataload // [value] + dup1 0x00 mstore // [value] + 0x04 calldataload // [to, value] + caller // [from, to, value] + + // Emit the approval event. + dup2 dup2 // [from, to, from, to, value] + __EVENT_HASH(APPROVAL_EVENT_SIGNATURE) // [sig, from, to, from, to, value] + 0x20 0x00 // [0, 32, sig, from, to, from, to, value] + log3 // [from, to, value] + + // Store the value at slot = keccak256(from . to) + STORE_ELEMENT_FROM_KEYS(0x00) +} + +/// @notice Domain Separator +/// @notice Returns the EIP-712 domain separator +#define macro DOMAIN_SEPARATOR() = takes (0) returns (0) { + NON_PAYABLE() // [] + _DOMAIN_SEPARATOR() // [domain separator] + 0x00 mstore // [domain separator] + 0x20 0x00 return // [] +} + +/// @notice Loads the EIP-712 domain separator +#define macro _DOMAIN_SEPARATOR() = takes (0) returns (1) { + chainid // [chainid] + [INITIAL_CHAIN_ID] sload // [INITIAL_CHAIN_ID, chainid] + eq // [INITIAL_CHAIN_ID == chainid] + useInitial jumpi // [] + COMPUTE_DOMAIN_SEPARATOR() // [computed domain separator] + done jump + + useInitial: + [INITIAL_DOMAIN_SEPARATOR] sload // [INITIAL_DOMAIN_SEPARATOR] + + done: +} + +/// @notice Computes the EIP-712 domain separator +#define macro COMPUTE_DOMAIN_SEPARATOR() = takes (0) returns (1) { + // WARNING: 0x00 - 0x3f (64 bytes): scratch space for hashing methods + // AS SUCH, WE STORE VARIABLES IN MEMORY STARTING AT 0x40 + + _GET_IMMUTABLE(NAME_OFFSET, 0xd0) // [name] + + [PERMIT_TYPEHASH] 0x40 mstore // [name] + 0x60 mstore // [] + 0x20 0x60 sha3 0x60 mstore // [] + + // 0x31 is hex for ascii for 1 + 0x31 0x80 mstore // [] + 0x02 0x80 sha3 0x80 mstore // [hash of "1"] + + chainid 0xa0 mstore // [chainid] + address 0xc0 mstore // [address(this)] + + 0xA0 0x40 sha3 // [hash] +} + +/// @notice Permit +/// @notice EIP 2612 Signed Approvals +#define macro PERMIT() = takes (0) returns (0) { + NON_PAYABLE() + // function permit arg calldata loc + // address owner 0x04 + // address spender 0x24 + // uint256 value 0x44 + // uint256 deadline 0x64 + // uint8 v 0x84 + // bytes32 r 0xa4 + // bytes32 s 0xc4 + + // check deadline + 0x64 calldataload // [deadline] + dup1 // [deadline, deadline] + timestamp // [timestamp, deadline, deadline] + gt // [timestamp > deadline, deadline] + expired jumpi // [deadline] + + // Calculate inner keccak + // keccak256( + // abi.encode( + // PERMIT_TYPEHASH, + // owner, + // spender, + // value, + // nonces[owner]++, + // deadline + // ) + // ) + 0x04 calldataload // [owner, deadline] + _NONCE_PLUS_PLUS() // [nonce, deadline] + 0x44 calldataload // [value, nonce, deadline] + 0x24 calldataload // [spender, value, nonce, deadline] + 0x04 calldataload // [owner, spender, value, nonce, deadline] + [PERMIT_TYPEHASH] // [permit hash, owner, spender, value, nonce, deadline] + 0x00 mstore // [owner, spender, value, nonce, deadline] + 0x20 mstore // [spender, value, nonce, deadline] + 0x40 mstore // [value, nonce, deadline] + 0x60 mstore // [nonce, deadline] + 0x80 mstore // [deadline] + 0xa0 mstore // [] + 0xc0 0x00 // [loc, len] + sha3 // [inner hash] + + // Grab the domain separator + _DOMAIN_SEPARATOR() // [domain separator, inner hash] + [X_1901] // [x1901, domain separator, inner hash] + + // Bitwise shifts + dup3 0xf0 shl // [inner hash << 0xf0, x1901, domain separator, inner hash] + + // Create the second word + dup3 0xf0 shl // [domain separator << 0xf0, inner hash << 0xf0, x1901, domain separator, inner hash] + dup5 0x10 shr or // [domain separator << 0xf0 | inner hash >> 0x10, inner hash << 0xf0, x1901, domain separator, inner hash] + + // Create the first word + dup4 dup4 swap1 0x10 shr or // [x1901 | domain separator >> 0x10, domain separator << 0xf0 | inner hash >> 0x10, inner hash << 0xf0, x1901, domain separator, inner hash] + + // Prepare memory mstore outer keccak + 0x40 mstore // [domain separator << 0xf0 | inner hash >> 0x10, inner hash << 0xf0, x1901, domain separator, inner hash] + 0x60 mstore // [inner hash << 0xf0, x1901, domain separator, inner hash] + 0x80 mstore // [x1901, domain separator, inner hash] + 0x42 0x40 // [loc, len, x1901, domain separator, inner hash] + sha3 // [outer hash, x1901, domain separator, inner hash] + + // Store signature in memory memory layout: + 0x00 mstore // [] 0x00 outer hash + 0x84 calldataload // [v] + 0x20 mstore // [] 0x00 outerhash 0x20 v + 0xa4 calldataload // [r] + 0x40 mstore // [] 0x00 outerhash 0x20 v 0x40 r + 0xc4 calldataload // [s] + 0x60 mstore // [] 0x00 outerhash 0x20 v 0x40 r 0x60 s + + // Prepare stack for later + 0x44 calldataload // [value] + 0x24 calldataload // [spender, value] + + // ecrecover + 0x20 // [32, spender, value] + 0x80 // [128, 32, spender, value] + 0x80 // [128, 128, 32, spender, value] + 0x00 // [0, 128, 128, 32, spender, value] + 0x1 // [ecrecover precompile address, 0, 128, 128, 32, spender, value] + 0xFFFFFFFF // [gas, ecrecover precompile address, 0, 128, 128, 32, spender, value] + staticcall // [success, spender, value] + + // Revert invalid signer if call failed + iszero invalidSigner jumpi // [spender, value] + + // Load the recovered address from memory + 0x80 mload // [recovered address, spender, value] + + // check for recovered 0 address + dup1 // [recovered address, recovered address, spender, value] + 0x00 eq // [recovered address == 0, recovered address, spender, value] + invalidSigner jumpi // [recovered address, spender, value] + + // check for address is owner + dup1 // [recovered address, recovered address, spender, value] + 0x04 calldataload // [owner, recovered address, recovered address, spender, value] + eq // [owner == recovered address, recovered address, spender, value] + iszero // [owner != recovered address, recovered address, spender, value] + invalidSigner jumpi // [recovered address, spender, value] + [APPROVAL_SLOT] // [slot, recovered address, spender, value] + STORE_ELEMENT_FROM_KEYS_2D(0x00) // [] + + // Emit the Approval event + 0x44 calldataload // [value] + 0x00 mstore // [] + 0x24 calldataload // [to] + 0x04 calldataload // [from, to] + __EVENT_HASH(Approval) // [sig, from, to] + 0x20 0x00 // [0, 32, sig, from, to] + log3 // [] + + // Stop Execution + stop // [] + + expired: + 0x5045524D49545F444541444C494E455F45585049524544000000000000000000 // ["PERMIT_DEADLINE_EXPIRED"] + 0x17 // [23 (length), "PERMIT_DEADLINE_EXPIRED"] + 0x00 // [0, 23 (length), "PERMIT_DEADLINE_EXPIRED"] + REQUIRE() + + invalidSigner: + 0x494E56414C49445F5349474E4552000000000000000000000000000000000000 // ["INVALID_SIGNER"] + 0x0e // [14 (length), "INVALID_SIGNER"] + 0x00 // [0, 14 (length), "INVALID_SIGNER"] + REQUIRE() +} + +/// @notice Takes an address off the stack, returns the current nonce for that address onto the stack. +/// @notice Increments the nonce for next time, +#define macro _NONCE_PLUS_PLUS() = takes (1) returns (1) { + // input stack // [account] + dup1 // [account, account] + [NONCE_SLOT] LOAD_ELEMENT_FROM_KEYS(0x00) // [currentNonce, account] + dup1 // [currentNonce, currentNonce, account] + 0x01 // [1, currentNonce, currentNonce, account] + add // [nextNonce, currentNonce, account] + dup3 // [account, nextNonce, currentNonce, account] + [NONCE_SLOT] STORE_ELEMENT_FROM_KEYS(0x00) // [currentNonce, account] + swap1 // clean up stack // [account, currentNonce] + pop // clean up stack // [currentNonce] +} + +/// @notice Nonces +/// @notice Returns the current nonce for an account +#define macro NONCES() = takes (0) returns (0) { + 0x04 calldataload // [account] + [NONCE_SLOT] LOAD_ELEMENT_FROM_KEYS(0x00) // [nonce] + 0x00 mstore // [] + 0x20 0x00 return // [] +} + +/// @notice Name +/// @notice Returns the token name string +#define macro NAME() = takes (0) returns (0) { + NON_PAYABLE() // [] + _GET_IMMUTABLE(NAME_OFFSET, 0x00) // [name_value] + _GET_IMMUTABLE(NAME_LENGTH_OFFSET, 0x00) // [name_length, name_value] + 0x20 0x00 mstore // [name_length, name_value] + 0x20 mstore // [name_value] + 0x40 mstore // [] + 0x60 0x00 return // [] +} + +/// @notice Symbol +/// @notice Returns the symbol of the token +#define macro SYMBOL() = takes (0) returns (0) { + NON_PAYABLE() // [] + _GET_IMMUTABLE(SYMBOL_OFFSET, 0x00) // [symbol_value] + _GET_IMMUTABLE(SYMBOL_LENGTH_OFFSET, 0x00) // [symbol_length, symbol_value] + 0x20 0x00 mstore // [symbol_length, symbol_value] + 0x20 mstore // [symbol_value] + 0x40 mstore // [] + 0x60 0x00 return // [] +} + +/// @notice Decimals +/// @notice Returns the token decimal representation +#define macro DECIMALS() = takes (0) returns (0) { + NON_PAYABLE() // [] + _GET_IMMUTABLE(DECIMALS_OFFSET, 0x00) // [decimals] + 0x00 mstore // [] + 0x20 0x00 return // [] +} + +/// @notice Balance Of +/// @notice Returns the token balance of an address +#define macro BALANCE_OF() = takes (0) returns (0) { + NON_PAYABLE() // [] + 0x04 calldataload // [account] + [BALANCE_SLOT] LOAD_ELEMENT_FROM_KEYS(0x00) // [balance] + 0x00 mstore // [] + 0x20 0x00 return // [] +} + +/// @notice Total Supply +/// @notice Returns the total supply of the token +#define macro TOTAL_SUPPLY() = takes (0) returns (0) { + NON_PAYABLE() // [] + [TOTAL_SUPPLY_SLOT] sload // [supply] + 0x00 mstore // [] + 0x20 0x00 return // [] +} + +/// @notice Allowance +/// @notice Returns the amount which a spender is allowed to transfer on behalf of an owner +#define macro ALLOWANCE() = takes (0) returns (0) { + NON_PAYABLE() // [] + 0x24 calldataload // [to] + 0x04 calldataload // [from, to] + [APPROVAL_SLOT] // [slot, from, to] + LOAD_ELEMENT_FROM_KEYS_2D(0x00) // [allowance] + 0x00 mstore // [] + 0x20 0x00 return // [] +} + +// MINT/BURN LOGIC + +#define macro _BURN() = takes(2) returns (0) { + // stack input: [value, from] + [ZERO_ADDRESS] // [zero, value, from] + swap2 swap1 // [value, from, zero] + + _TRANSFER_TAKE_FROM() // [value, from, zero] + dup1 // [value, value, from, zero] + [TOTAL_SUPPLY_SLOT] sload // [supply, value, value, from, zero] + sub // [supply-value, value, from, zero] + [TOTAL_SUPPLY_SLOT] sstore // [value, from, zero] + + // Emit the transfer event. + 0x00 mstore // [from, zero] + __EVENT_HASH(Transfer) // [sig, from, zero] + 0x20 0x00 // [0, 32, sig, from, zero] + log3 // [] +} + +/// @notice Mints tokens to a specified address +#define macro _MINT() = takes (2) returns (0) { + // Input stack: [value, to] + dup2 // [to, value, to] + swap1 // [value, to, to] + _TRANSFER_GIVE_TO() // [value, to, to] + + // Update totalSupply + dup1 // [value, value, to, to] + [TOTAL_SUPPLY_SLOT] sload // [supply, value, value, to, to] + add // [supply + value, value, to, to] + [TOTAL_SUPPLY_SLOT] sstore // [value, to, to] + + // Emit the transfer event. + 0x00 mstore // [to, to] + [ZERO_ADDRESS] // [address(0), to, to] + __EVENT_HASH(Transfer) // [sig, from, to, to] + 0x20 0x00 // [0, 32, sig, from, to, to] + log3 pop // [] +} + + +// Function Dispatching +#define macro ERC20_MAIN() = takes (1) returns (1) { + // Identify which function is being called. + // [func sig] + + dup1 __FUNC_SIG(permit) eq permitJump jumpi + dup1 __FUNC_SIG(nonces) eq noncesJump jumpi + + dup1 __FUNC_SIG(name) eq nameJump jumpi + dup1 __FUNC_SIG(symbol) eq symbolJump jumpi + dup1 __FUNC_SIG(decimals) eq decimalsJump jumpi + dup1 __FUNC_SIG(DOMAIN_SEPARATOR) eq domainSeparatorJump jumpi + + dup1 __FUNC_SIG(totalSupply) eq totalSupplyJump jumpi + dup1 __FUNC_SIG(balanceOf) eq balanceOfJump jumpi + dup1 __FUNC_SIG(allowance) eq allowanceJump jumpi + + dup1 __FUNC_SIG(transfer) eq transferJump jumpi + dup1 __FUNC_SIG(transferFrom) eq transferFromJump jumpi + dup1 __FUNC_SIG(approve) eq approveJump jumpi + + // Bubble up to the parent macro + no_match jump + + allowanceJump: + ALLOWANCE() + approveJump: + APPROVE() + balanceOfJump: + BALANCE_OF() + decimalsJump: + DECIMALS() + domainSeparatorJump: + DOMAIN_SEPARATOR() + nameJump: + NAME() + noncesJump: + NONCES() + permitJump: + PERMIT() + symbolJump: + SYMBOL() + totalSupplyJump: + TOTAL_SUPPLY() + transferFromJump: + TRANSFER_FROM() + transferJump: + TRANSFER() + + no_match: +} diff --git a/src/tokens/__TEMP__olyemymwzenpqjpuukwgitehudafctpwERC20.huff b/src/tokens/__TEMP__olyemymwzenpqjpuukwgitehudafctpwERC20.huff new file mode 100644 index 00000000..75ecc0af --- /dev/null +++ b/src/tokens/__TEMP__olyemymwzenpqjpuukwgitehudafctpwERC20.huff @@ -0,0 +1,676 @@ + +#define function mint(address, uint256) nonpayable returns () +#define function burn(address, uint256) nonpayable returns () + +#define macro BURN() = takes (0) returns (0) { + NON_PAYABLE() + // Setup the stack for the burn function. + 0x04 calldataload // [from] + 0x24 calldataload // [value, from] + + // Call ERC20.huff's _BURN macro + _BURN() // [] + + // Stop Execution + stop // [] +} + +#define macro MINT() = takes (0) returns (0) { + NON_PAYABLE() + + // Setup the stack for the mint function. + 0x04 calldataload // [to] + 0x24 calldataload // [value, to] + + // Call ERC20.huff's _MINT macro + _MINT() // [] + + // Stop Execution + stop // [] +} + +#define macro CONSTRUCTOR() = takes (0) returns (0) { + ERC20_CONSTRUCTOR() +} + +#define macro MAIN() = takes (0) returns (0) { + 0x00 calldataload 0xE0 shr // [sig] + + dup1 __FUNC_SIG(mint) eq mint jumpi // [sig] + dup1 __FUNC_SIG(burn) eq burn jumpi // [sig] + + ERC20_MAIN() // [sig] + + // Revert if no selector matches + 0x00 0x00 revert + + mint: + MINT() + burn: + BURN() +} + +/// @title ERC20 +/// @notice SPDX-License-Identifier: MIT +/// @author asnared +/// @author devtooligan +/// @notice Modern and gas efficient ERC20 + EIP-2612 implementation +/// @notice Adapted from Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC20.sol) + +// Imports +#include "../utils/Errors.huff" +#include "../auth/NonPayable.huff" +#include "../data-structures/Hashmap.huff" + +// Interface +#define function allowance(address,address) view returns (uint256) +#define function approve(address,uint256) nonpayable returns () +#define function balanceOf(address) view returns (uint256) +#define function DOMAIN_SEPARATOR() view returns (bytes32) +#define function nonces(address) view returns (uint256) +#define function permit(address,address,uint256,uint256,uint8,bytes32,bytes32) nonpayable returns () +#define function totalSupply() view returns (uint256) +#define function transfer(address,uint256) nonpayable returns () +#define function transferFrom(address,address,uint256) nonpayable returns () + +// Events +#define event Approval(address indexed, address indexed, uint256) +#define event Transfer(address, address, uint256) + +// Metadata +#define function decimals() nonpayable returns (uint8) +#define function name() nonpayable returns (string) +#define function symbol() nonpayable returns (string) + +// ERC20 Storage +#define constant TOTAL_SUPPLY_SLOT = FREE_STORAGE_POINTER() +#define constant BALANCE_SLOT = FREE_STORAGE_POINTER() +#define constant APPROVAL_SLOT = FREE_STORAGE_POINTER() + +// EIP-2612 STORAGE +#define constant INITIAL_CHAIN_ID = FREE_STORAGE_POINTER() +#define constant INITIAL_DOMAIN_SEPARATOR = FREE_STORAGE_POINTER() +#define constant NONCE_SLOT = FREE_STORAGE_POINTER() + +// Immutables offsets +#define constant DECIMALS_OFFSET = 0x0000000000000000000000000000000000000000000000000000000000000020 +#define constant NAME_OFFSET = 0x00000000000000000000000000000000000000000000000000000000000000a0 +#define constant NAME_LENGTH_OFFSET = 0x00000000000000000000000000000000000000000000000000000000000000c0 +#define constant SYMBOL_OFFSET = 0x0000000000000000000000000000000000000000000000000000000000000040 +#define constant SYMBOL_LENGTH_OFFSET = 0x0000000000000000000000000000000000000000000000000000000000000060 + +// PERMIT_TYPEHASH = keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)") +#define constant PERMIT_TYPEHASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9 +#define constant X_1901 = 0x1901000000000000000000000000000000000000000000000000000000000000 + +// Utility Constants +#define constant UINT_256_MAX = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +#define constant ERROR_SIG = 0x08c379a000000000000000000000000000000000000000000000000000000000 +#define constant ZERO_ADDRESS = 0x0000000000000000000000000000000000000000 + +/// @notice Constructor +/// @notice Sets the initial domain separator and chain ID +#define macro ERC20_CONSTRUCTOR() = takes (0) returns (0) { + // Constructor arguments: + // ?, name_size, name, ?, symbol_size, symbol, decimals + + // This constructor will return the runtime bytecode with all the + // constructor arguments concatenated at the end. + + chainid [INITIAL_CHAIN_ID] sstore // [] + COMPUTE_DOMAIN_SEPARATOR() // [DOMAIN SEPARATOR] + [INITIAL_DOMAIN_SEPARATOR] sstore // [] + + // Copy the runtime bytecode with constructor argument concatenated. + 0x67 // [offset] - constructor code size + dup1 // [offset, offset] + codesize // [total_size, offset, offset] + sub // [runtime_size, offset] + dup1 // [runtime_size, runtime_size, offset] + swap2 // [offset, runtime_size, runtime_size] + returndatasize // [return_offset, offset, runtime_size, runtime_size] + codecopy // [runtime_size] + + // Return the runtime bytecode. + returndatasize // [return_offset, runtime_size] + return // [] +} + +/// @notice Retrives an "immutable" from the runtime bytecode. +#define macro _GET_IMMUTABLE(offset_end, free_memory) = takes (0) returns (1) { + 0x20 // [size] + codesize sub // [offset_code, size] + // [offset_memory, offset_code, size] + codecopy // [] + mload // [value] +} + +/// @notice Approve +/// @notice Grants approval to an operator to transfer tokens on behalf of the sender. +#define macro APPROVE() = takes (0) returns (0) { + NON_PAYABLE() // [] + + 0x24 calldataload // [value] + 0x04 calldataload // [to, value] + caller // [from, to, value] + [APPROVAL_SLOT] // [slot, from, to, value] + STORE_ELEMENT_FROM_KEYS_2D(0x00) // [] + + // Emit the Approval event + 0x24 calldataload // [value] + 0x00 mstore // [] + 0x04 calldataload // [to] + caller // [from, to] + __EVENT_HASH(Approval) // [sig, from, to] + 0x20 0x00 // [0, 32, sig, from, to] + log3 // [] + + // Return 01 for true + 0x01 0x00 mstore // [] + 0x20 0x00 return // [] +} + +/// @notice Transfer +/// @notice Non-Payable function that transfers an amount of tokens from the sender to a recipient. +#define macro TRANSFER() = takes (0) returns (0) { + NON_PAYABLE() + + // Setup the stack for the transfer function. + 0x04 calldataload // [to] + caller // [from, to] + 0x24 calldataload // [value, from, to] + + // Update the balances of the sender and recipient. + _TRANSFER_TAKE_FROM() // [value, from, to] + _TRANSFER_GIVE_TO() // [value, from, to] + + // Emit the transfer event. + 0x00 mstore // [from, to] + __EVENT_HASH(Transfer) // [sig, from, to] + 0x20 0x00 // [0, 32, sig, from, to] + log3 // [] + + // Return "1" to represent a succesful transfer. + 0x01 0x00 mstore // [] + 0x20 0x00 return // [] +} + +/// @notice Transfer From +/// @notice Non-Payable function that transfers an amount of tokens from an address to a recipient. +#define macro TRANSFER_FROM() = takes (0) returns (0) { + NON_PAYABLE() // [] + + // Setup the stack for the transfer function. + 0x24 calldataload // [to] + 0x04 calldataload // [from, to] + caller // [msg.sender, from, to] + dup2 // [from, msg.sender, from, to] + [APPROVAL_SLOT] // [slot, from, msg.sender, from, to] + + // Check for max approval + LOAD_ELEMENT_FROM_KEYS_2D(0x00) // [approved, from, to] + dup1 // [approved, approved, from, to] + 0x44 calldataload // [value, approved, approved, from, to] + + // Check isOwner + dup4 // [from, value, approved, approved, from, to] + caller // [msg.sender, from, value, approved, approved, from, to] + eq // [msg.sender == from, value, approved, approved, from, to] + approved1 jumpi // [value, approved, approved, from, to] + + // Check max approval + dup2 // [approved, value, approved, approved, from, to] + [UINT_256_MAX] // [type(uint).max, approved, value, approved, approved, from, to] + eq // [type(uint).max == approved, value, approved, approved, from, to] + approved1 jumpi // [value, approved, approved, from, to] + + // Check has approval + gt // [value > approved, approved, from, to] + insufficientApproval jumpi // [approved, from, to] + + // Adjust approval + 0x44 calldataload // [value, approved, from, to] + swap1 // [approved, value, from, to] + sub // [approved - value => newApprovalValue, from, to] + caller // [msg.sender, newApprovalValue, from, to] + dup3 // [from, msg.sender, newApprovalValue, from, to] + [APPROVAL_SLOT] // [slot, from, msg.sender, newApprovalValue, from, to] + STORE_ELEMENT_FROM_KEYS_2D(0x00) // [from, to] + approved2 jump // [from, to] + + approved1: // [value, approved, approved, from, to] + pop pop pop // [from, to] + + approved2: // [from, to] + 0x44 calldataload // [value, from, to] + + // Update the balances of the sender and recipient. + _TRANSFER_TAKE_FROM() // [value, from, to] + _TRANSFER_GIVE_TO() // [value, from, to] + + // Emit the transfer event. + 0x00 mstore // [from, to] + __EVENT_HASH(Transfer) // [sig, from, to] + 0x20 0x00 // [0, 32, sig, from, to] + log3 // [] + + // Return "1" to represent a succesful transfer. + 0x01 0x00 mstore // [] + 0x20 0x00 return // [] + + insufficientApproval: + 0x00 0x00 revert // [] +} + +/// @notice Transfers an amount of tokens from +#define macro _TRANSFER_TAKE_FROM() = takes (3) returns (3) { + // input stack: [value, from, to] + dup2 [BALANCE_SLOT] LOAD_ELEMENT_FROM_KEYS(0x00) // [balance, value, from, to] // [from, value, from, to] + dup1 // [balance, balance, value, from, to] + dup3 // [value, balance, balance, value, from, to] + gt // [value > balance, balance, value, from, to] + iszero // [value <= balance, balance, value, from, to] + valid jumpi // [balance, value, from, to] + + // Insufficient balance + 0x00 0x00 revert // [] + + // Update the sender's balance. + valid: + dup2 // [value, balance, value, from, to] + swap1 // [balance, value, value, from, to] + sub // [balance - value, value, from, to] + dup3 // [from, balance - value, value, from, to] + [BALANCE_SLOT] STORE_ELEMENT_FROM_KEYS(0x00) // [value, from, to] +} + +/// @notice Transfers an amount of tokens from one address to another. +#define macro _TRANSFER_GIVE_TO() = takes (3) returns (3) { + // input stack: [value, from, to] + dup3 // [to, value, from, to] + dup2 // [value, to, value, from, to] + swap1 // [to, value, value, from, to] + [BALANCE_SLOT] LOAD_ELEMENT_FROM_KEYS(0x00) // [balance, value, value, from, to] + add // [balance + value, value, from, to] + dup4 // [to, balance + value, value, from, to] + [BALANCE_SLOT] STORE_ELEMENT_FROM_KEYS(0x00) // [value, from, to] +} + +/// @notice Approve +/// @notice Approves an address to spend an amount of tokens on the caller's behalf +#define macro APPROVE() = takes (0) returns (0) { + 0x24 calldataload // [value] + dup1 0x00 mstore // [value] + 0x04 calldataload // [to, value] + caller // [from, to, value] + + // Emit the approval event. + dup2 dup2 // [from, to, from, to, value] + __EVENT_HASH(APPROVAL_EVENT_SIGNATURE) // [sig, from, to, from, to, value] + 0x20 0x00 // [0, 32, sig, from, to, from, to, value] + log3 // [from, to, value] + + // Store the value at slot = keccak256(from . to) + STORE_ELEMENT_FROM_KEYS(0x00) +} + +/// @notice Domain Separator +/// @notice Returns the EIP-712 domain separator +#define macro DOMAIN_SEPARATOR() = takes (0) returns (0) { + NON_PAYABLE() // [] + _DOMAIN_SEPARATOR() // [domain separator] + 0x00 mstore // [domain separator] + 0x20 0x00 return // [] +} + +/// @notice Loads the EIP-712 domain separator +#define macro _DOMAIN_SEPARATOR() = takes (0) returns (1) { + chainid // [chainid] + [INITIAL_CHAIN_ID] sload // [INITIAL_CHAIN_ID, chainid] + eq // [INITIAL_CHAIN_ID == chainid] + useInitial jumpi // [] + COMPUTE_DOMAIN_SEPARATOR() // [computed domain separator] + done jump + + useInitial: + [INITIAL_DOMAIN_SEPARATOR] sload // [INITIAL_DOMAIN_SEPARATOR] + + done: +} + +/// @notice Computes the EIP-712 domain separator +#define macro COMPUTE_DOMAIN_SEPARATOR() = takes (0) returns (1) { + // WARNING: 0x00 - 0x3f (64 bytes): scratch space for hashing methods + // AS SUCH, WE STORE VARIABLES IN MEMORY STARTING AT 0x40 + + _GET_IMMUTABLE(NAME_OFFSET, 0xd0) // [name] + + [PERMIT_TYPEHASH] 0x40 mstore // [name] + 0x60 mstore // [] + 0x20 0x60 sha3 0x60 mstore // [] + + // 0x31 is hex for ascii for 1 + 0x31 0x80 mstore // [] + 0x02 0x80 sha3 0x80 mstore // [hash of "1"] + + chainid 0xa0 mstore // [chainid] + address 0xc0 mstore // [address(this)] + + 0xA0 0x40 sha3 // [hash] +} + +/// @notice Permit +/// @notice EIP 2612 Signed Approvals +#define macro PERMIT() = takes (0) returns (0) { + NON_PAYABLE() + // function permit arg calldata loc + // address owner 0x04 + // address spender 0x24 + // uint256 value 0x44 + // uint256 deadline 0x64 + // uint8 v 0x84 + // bytes32 r 0xa4 + // bytes32 s 0xc4 + + // check deadline + 0x64 calldataload // [deadline] + dup1 // [deadline, deadline] + timestamp // [timestamp, deadline, deadline] + gt // [timestamp > deadline, deadline] + expired jumpi // [deadline] + + // Calculate inner keccak + // keccak256( + // abi.encode( + // PERMIT_TYPEHASH, + // owner, + // spender, + // value, + // nonces[owner]++, + // deadline + // ) + // ) + 0x04 calldataload // [owner, deadline] + _NONCE_PLUS_PLUS() // [nonce, deadline] + 0x44 calldataload // [value, nonce, deadline] + 0x24 calldataload // [spender, value, nonce, deadline] + 0x04 calldataload // [owner, spender, value, nonce, deadline] + [PERMIT_TYPEHASH] // [permit hash, owner, spender, value, nonce, deadline] + 0x00 mstore // [owner, spender, value, nonce, deadline] + 0x20 mstore // [spender, value, nonce, deadline] + 0x40 mstore // [value, nonce, deadline] + 0x60 mstore // [nonce, deadline] + 0x80 mstore // [deadline] + 0xa0 mstore // [] + 0xc0 0x00 // [loc, len] + sha3 // [inner hash] + + // Grab the domain separator + _DOMAIN_SEPARATOR() // [domain separator, inner hash] + [X_1901] // [x1901, domain separator, inner hash] + + // Bitwise shifts + dup3 0xf0 shl // [inner hash << 0xf0, x1901, domain separator, inner hash] + + // Create the second word + dup3 0xf0 shl // [domain separator << 0xf0, inner hash << 0xf0, x1901, domain separator, inner hash] + dup5 0x10 shr or // [domain separator << 0xf0 | inner hash >> 0x10, inner hash << 0xf0, x1901, domain separator, inner hash] + + // Create the first word + dup4 dup4 swap1 0x10 shr or // [x1901 | domain separator >> 0x10, domain separator << 0xf0 | inner hash >> 0x10, inner hash << 0xf0, x1901, domain separator, inner hash] + + // Prepare memory mstore outer keccak + 0x40 mstore // [domain separator << 0xf0 | inner hash >> 0x10, inner hash << 0xf0, x1901, domain separator, inner hash] + 0x60 mstore // [inner hash << 0xf0, x1901, domain separator, inner hash] + 0x80 mstore // [x1901, domain separator, inner hash] + 0x42 0x40 // [loc, len, x1901, domain separator, inner hash] + sha3 // [outer hash, x1901, domain separator, inner hash] + + // Store signature in memory memory layout: + 0x00 mstore // [] 0x00 outer hash + 0x84 calldataload // [v] + 0x20 mstore // [] 0x00 outerhash 0x20 v + 0xa4 calldataload // [r] + 0x40 mstore // [] 0x00 outerhash 0x20 v 0x40 r + 0xc4 calldataload // [s] + 0x60 mstore // [] 0x00 outerhash 0x20 v 0x40 r 0x60 s + + // Prepare stack for later + 0x44 calldataload // [value] + 0x24 calldataload // [spender, value] + + // ecrecover + 0x20 // [32, spender, value] + 0x80 // [128, 32, spender, value] + 0x80 // [128, 128, 32, spender, value] + 0x00 // [0, 128, 128, 32, spender, value] + 0x1 // [ecrecover precompile address, 0, 128, 128, 32, spender, value] + 0xFFFFFFFF // [gas, ecrecover precompile address, 0, 128, 128, 32, spender, value] + staticcall // [success, spender, value] + + // Revert invalid signer if call failed + iszero invalidSigner jumpi // [spender, value] + + // Load the recovered address from memory + 0x80 mload // [recovered address, spender, value] + + // check for recovered 0 address + dup1 // [recovered address, recovered address, spender, value] + 0x00 eq // [recovered address == 0, recovered address, spender, value] + invalidSigner jumpi // [recovered address, spender, value] + + // check for address is owner + dup1 // [recovered address, recovered address, spender, value] + 0x04 calldataload // [owner, recovered address, recovered address, spender, value] + eq // [owner == recovered address, recovered address, spender, value] + iszero // [owner != recovered address, recovered address, spender, value] + invalidSigner jumpi // [recovered address, spender, value] + [APPROVAL_SLOT] // [slot, recovered address, spender, value] + STORE_ELEMENT_FROM_KEYS_2D(0x00) // [] + + // Emit the Approval event + 0x44 calldataload // [value] + 0x00 mstore // [] + 0x24 calldataload // [to] + 0x04 calldataload // [from, to] + __EVENT_HASH(Approval) // [sig, from, to] + 0x20 0x00 // [0, 32, sig, from, to] + log3 // [] + + // Stop Execution + stop // [] + + expired: + 0x5045524D49545F444541444C494E455F45585049524544000000000000000000 // ["PERMIT_DEADLINE_EXPIRED"] + 0x17 // [23 (length), "PERMIT_DEADLINE_EXPIRED"] + 0x00 // [0, 23 (length), "PERMIT_DEADLINE_EXPIRED"] + REQUIRE() + + invalidSigner: + 0x494E56414C49445F5349474E4552000000000000000000000000000000000000 // ["INVALID_SIGNER"] + 0x0e // [14 (length), "INVALID_SIGNER"] + 0x00 // [0, 14 (length), "INVALID_SIGNER"] + REQUIRE() +} + +/// @notice Takes an address off the stack, returns the current nonce for that address onto the stack. +/// @notice Increments the nonce for next time, +#define macro _NONCE_PLUS_PLUS() = takes (1) returns (1) { + // input stack // [account] + dup1 // [account, account] + [NONCE_SLOT] LOAD_ELEMENT_FROM_KEYS(0x00) // [currentNonce, account] + dup1 // [currentNonce, currentNonce, account] + 0x01 // [1, currentNonce, currentNonce, account] + add // [nextNonce, currentNonce, account] + dup3 // [account, nextNonce, currentNonce, account] + [NONCE_SLOT] STORE_ELEMENT_FROM_KEYS(0x00) // [currentNonce, account] + swap1 // clean up stack // [account, currentNonce] + pop // clean up stack // [currentNonce] +} + +/// @notice Nonces +/// @notice Returns the current nonce for an account +#define macro NONCES() = takes (0) returns (0) { + 0x04 calldataload // [account] + [NONCE_SLOT] LOAD_ELEMENT_FROM_KEYS(0x00) // [nonce] + 0x00 mstore // [] + 0x20 0x00 return // [] +} + +/// @notice Name +/// @notice Returns the token name string +#define macro NAME() = takes (0) returns (0) { + NON_PAYABLE() // [] + _GET_IMMUTABLE(NAME_OFFSET, 0x00) // [name_value] + _GET_IMMUTABLE(NAME_LENGTH_OFFSET, 0x00) // [name_length, name_value] + 0x20 0x00 mstore // [name_length, name_value] + 0x20 mstore // [name_value] + 0x40 mstore // [] + 0x60 0x00 return // [] +} + +/// @notice Symbol +/// @notice Returns the symbol of the token +#define macro SYMBOL() = takes (0) returns (0) { + NON_PAYABLE() // [] + _GET_IMMUTABLE(SYMBOL_OFFSET, 0x00) // [symbol_value] + _GET_IMMUTABLE(SYMBOL_LENGTH_OFFSET, 0x00) // [symbol_length, symbol_value] + 0x20 0x00 mstore // [symbol_length, symbol_value] + 0x20 mstore // [symbol_value] + 0x40 mstore // [] + 0x60 0x00 return // [] +} + +/// @notice Decimals +/// @notice Returns the token decimal representation +#define macro DECIMALS() = takes (0) returns (0) { + NON_PAYABLE() // [] + _GET_IMMUTABLE(DECIMALS_OFFSET, 0x00) // [decimals] + 0x00 mstore // [] + 0x20 0x00 return // [] +} + +/// @notice Balance Of +/// @notice Returns the token balance of an address +#define macro BALANCE_OF() = takes (0) returns (0) { + NON_PAYABLE() // [] + 0x04 calldataload // [account] + [BALANCE_SLOT] LOAD_ELEMENT_FROM_KEYS(0x00) // [balance] + 0x00 mstore // [] + 0x20 0x00 return // [] +} + +/// @notice Total Supply +/// @notice Returns the total supply of the token +#define macro TOTAL_SUPPLY() = takes (0) returns (0) { + NON_PAYABLE() // [] + [TOTAL_SUPPLY_SLOT] sload // [supply] + 0x00 mstore // [] + 0x20 0x00 return // [] +} + +/// @notice Allowance +/// @notice Returns the amount which a spender is allowed to transfer on behalf of an owner +#define macro ALLOWANCE() = takes (0) returns (0) { + NON_PAYABLE() // [] + 0x24 calldataload // [to] + 0x04 calldataload // [from, to] + [APPROVAL_SLOT] // [slot, from, to] + LOAD_ELEMENT_FROM_KEYS_2D(0x00) // [allowance] + 0x00 mstore // [] + 0x20 0x00 return // [] +} + +// MINT/BURN LOGIC + +#define macro _BURN() = takes(2) returns (0) { + // stack input: [value, from] + [ZERO_ADDRESS] // [zero, value, from] + swap2 swap1 // [value, from, zero] + + _TRANSFER_TAKE_FROM() // [value, from, zero] + dup1 // [value, value, from, zero] + [TOTAL_SUPPLY_SLOT] sload // [supply, value, value, from, zero] + sub // [supply-value, value, from, zero] + [TOTAL_SUPPLY_SLOT] sstore // [value, from, zero] + + // Emit the transfer event. + 0x00 mstore // [from, zero] + __EVENT_HASH(Transfer) // [sig, from, zero] + 0x20 0x00 // [0, 32, sig, from, zero] + log3 // [] +} + +/// @notice Mints tokens to a specified address +#define macro _MINT() = takes (2) returns (0) { + // Input stack: [value, to] + dup2 // [to, value, to] + swap1 // [value, to, to] + _TRANSFER_GIVE_TO() // [value, to, to] + + // Update totalSupply + dup1 // [value, value, to, to] + [TOTAL_SUPPLY_SLOT] sload // [supply, value, value, to, to] + add // [supply + value, value, to, to] + [TOTAL_SUPPLY_SLOT] sstore // [value, to, to] + + // Emit the transfer event. + 0x00 mstore // [to, to] + [ZERO_ADDRESS] // [address(0), to, to] + __EVENT_HASH(Transfer) // [sig, from, to, to] + 0x20 0x00 // [0, 32, sig, from, to, to] + log3 pop // [] +} + + +// Function Dispatching +#define macro ERC20_MAIN() = takes (1) returns (1) { + // Identify which function is being called. + // [func sig] + + dup1 __FUNC_SIG(permit) eq permitJump jumpi + dup1 __FUNC_SIG(nonces) eq noncesJump jumpi + + dup1 __FUNC_SIG(name) eq nameJump jumpi + dup1 __FUNC_SIG(symbol) eq symbolJump jumpi + dup1 __FUNC_SIG(decimals) eq decimalsJump jumpi + dup1 __FUNC_SIG(DOMAIN_SEPARATOR) eq domainSeparatorJump jumpi + + dup1 __FUNC_SIG(totalSupply) eq totalSupplyJump jumpi + dup1 __FUNC_SIG(balanceOf) eq balanceOfJump jumpi + dup1 __FUNC_SIG(allowance) eq allowanceJump jumpi + + dup1 __FUNC_SIG(transfer) eq transferJump jumpi + dup1 __FUNC_SIG(transferFrom) eq transferFromJump jumpi + dup1 __FUNC_SIG(approve) eq approveJump jumpi + + // Bubble up to the parent macro + no_match jump + + allowanceJump: + ALLOWANCE() + approveJump: + APPROVE() + balanceOfJump: + BALANCE_OF() + decimalsJump: + DECIMALS() + domainSeparatorJump: + DOMAIN_SEPARATOR() + nameJump: + NAME() + noncesJump: + NONCES() + permitJump: + PERMIT() + symbolJump: + SYMBOL() + totalSupplyJump: + TOTAL_SUPPLY() + transferFromJump: + TRANSFER_FROM() + transferJump: + TRANSFER() + + no_match: +} diff --git a/src/tokens/__TEMP__oqsfkvbhimsywiqwbdlilqoxezxnqvipERC721.huff b/src/tokens/__TEMP__oqsfkvbhimsywiqwbdlilqoxezxnqvipERC721.huff new file mode 100644 index 00000000..17f4c60b --- /dev/null +++ b/src/tokens/__TEMP__oqsfkvbhimsywiqwbdlilqoxezxnqvipERC721.huff @@ -0,0 +1,787 @@ + +#define function mint(address, uint256) payable returns () +#define function burn(uint256) nonpayable returns () + +#define function mint(address, uint256) payable returns () +#define function burn(uint256) nonpayable returns () + +#define function safeMint(address to, uint256 tokenId, bytes memory data) payable returns () +#define function safeMint(address to, uint256 tokenId) payable returns () + +#define macro CONSTRUCTOR() = takes (0) returns (0) { + ERC721_CONSTRUCTOR() +} + +#define macro MINT() = takes (0) returns (0) { + 0x24 calldataload // [tokenId] + 0x04 calldataload // [to, tokenId] + _MINT() + stop +} + +#define macro BURN() = takes (0) returns (0) { + 0x04 calldataload // [tokenId] + _BURN() + stop +} + +#define macro SAFE_MINT() = takes (0) returns (0) { + 0x24 calldataload // [tokenId] + 0x04 calldataload // [to, tokenId] + _MINT() + + // Safe Logic + // Make sure we can transfer to the recipient + 0x04 calldataload // [to] + dup1 extcodesize // [to.code.length, to] + iszero safe jumpi // [to] + + // onERC721Received Selector + 0x150b7a02 dup1 // [onERC721Received, onERC721Received, to] + 0xE0 shl // [onERC721Received_shifted, onERC721Received, to] + + // Store the left-shifted selector for call + 0x20 mstore // [onERC721Received, to] + + // Store the msg.sender as the first arg + caller 0x24 mstore // [onERC721Received, to] + + // Store address(0) as the second arg + 0x00 // [address(0), onERC721Received, to] + 0x44 mstore // [onERC721Received, to] + + // Id is the third arg + 0x24 calldataload // [tokenId, onERC721Received, to] + 0x64 mstore // [onERC721Received, to] + + // Blank bytes array as 4th arg (no data) + 0x80 0x84 mstore + 0x00 0xA4 mstore + + // Call address(to).onERC721Received(msg.sender, from, tokenId, "") + 0x20 // [retSize, onERC721Received, to] + 0x00 // [retOffset, retSize, onERC721Received, to] + 0xA4 // [argSize, retOffset, retSize, onERC721Received, to] + dup3 // [argOffset, argSize, retOffset, retSize, onERC721Received, to] + dup3 // [value, argOffset, argSize, retOffset, retSize, onERC721Received, to] + dup7 // [to, value, argOffset, argSize, retOffset, retSize, onERC721Received, to] + gas // [gas, to, value, argOffset, argSize, retOffset, retSize, onERC721Received, to] + call // [success, onERC721Received, to] + + // Revert if call isn't successful + cont jumpi // [onERC721Received, to] + 0x00 dup1 revert + cont: + + // Compare the return data to the onERC721Received selector + 0x00 mload 0xE0 shr // [response, onERC721Received, to] + eq safe jumpi // [to] + + // Revert if the return data is not accepted + UNSAFE_RECIPIENT(0x00) + + // Stop execution if safe + safe: + stop +} + +#define macro SAFE_MINT_WITH_DATA() = takes (0) returns (0) { + 0x44 calldataload // [data] + 0x24 calldataload // [tokenId, data] + 0x04 calldataload // [to, tokenId, data] + _MINT() + + // Make sure we can transfer to the recipient + 0x04 calldataload // [to] + dup1 extcodesize // [to.code.length, to] + iszero safe jumpi // [to] + + // onERC721Received Selector + 0x150b7a02 dup1 // [onERC721Received, onERC721Received, to] + 0xE0 shl // [onERC721Received_shifted, onERC721Received, to] + + // Store the left-shifted selector for call + 0x20 mstore // [onERC721Received, to] + + // Store the msg.sender as the first arg + caller 0x24 mstore // [onERC721Received, to] + + // Store address(0) as the second arg + 0x00 // [address(0), onERC721Received, to] + 0x44 mstore // [onERC721Received, to] + + // Id is the third arg + 0x24 calldataload // [tokenId, onERC721Received, to] + 0x64 mstore // [onERC721Received, to] + + // Store the pointer to the data length + 0x80 0x84 mstore // [onERC721Received, to] + + 0x64 calldataload // [len(data), onERC721Received, to] + 0x05 shl // [len(data) * 0x20, onERC721Received, to] + 0x20 add // [len(data) * 0x20 + 0x20, onERC721Received, to] + dup1 // [len(data) * 0x20 + 0x20, len(data) * 0x20 + 0x20, onERC721received, to] + 0x64 // [0x64, len(data) * 0x20 + 0x20, len(data) * 0x20 + 0x20, onERC721received, to] + 0xA4 // [0x84, 0x64, len(data) * 0x20 + 0x20, len(data) * 0x20 + 0x20, onERC721received, to] + calldatacopy // [len(bytes), onERC721received, to] + + // Call address(to).onERC721Received(msg.sender, from, tokenId, bytes) + 0x20 // [retSize, len(bytes), onERC721Received, to] + 0x00 // [retOffset, retSize, len(bytes), onERC721Received, to] + swap1 swap2 // [len(bytes), retOffset, retSize, onERC721Received, to] + 0x84 add // [argSize, retOffset, retSize, onERC721Received, to] + dup3 // [argOffset, argSize, retOffset, retSize, len(bytes), onERC721Received, to] + dup3 // [value, argOffset, argSize, retOffset, retSize, len(bytes), onERC721Received, to] + dup7 // [to, value, argOffset, argSize, retOffset, retSize, len(bytes), onERC721Received, to] + gas // [gas, to, value, argOffset, argSize, retOffset, retSize, len(bytes), onERC721Received, to] + call // [success, len(bytes), onERC721Received, to] + + // Revert if call isn't successful + selector_call_success jumpi // [len(bytes), onERC721Received, to] + 0x00 dup1 revert + selector_call_success: + + // Compare the return data to the onERC721Received selector + 0x00 mload 0xE0 shr // [response, onERC721Received, to] + eq safe jumpi // [to] + + // Revert if the return data is not accepted + UNSAFE_RECIPIENT(0x00) + + // Stop execution if safe + safe: + stop + +} + +// Function Dispatch +#define macro MAIN() = takes (0) returns (0) { + 0x00 calldataload 0xE0 shr // [sig] + + // Mint and Burning Functions + dup1 __FUNC_SIG(mint) eq mint_jump jumpi + dup1 __FUNC_SIG(burn) eq burn_jump jumpi + + dup1 __FUNC_SIG("safeMint(address,uint256)") eq safe_mint jumpi + dup1 __FUNC_SIG("safeMint(address,uint256,bytes)") eq safe_mint_with_data jumpi + + dup1 __FUNC_SIG(approve) eq approve jumpi + dup1 __FUNC_SIG(setApprovalForAll) eq setApprovalForAll jumpi + + dup1 __FUNC_SIG(transferFrom) eq transferFrom jumpi + dup1 __FUNC_SIG(safeTransferFrom) eq safeTransferFrom jumpi + + dup1 __FUNC_SIG(name) eq name jumpi + dup1 __FUNC_SIG(symbol) eq symbol jumpi + dup1 __FUNC_SIG(tokenURI) eq tokenURI jumpi + dup1 __FUNC_SIG(supportsInterface) eq supportsInterface jumpi + + dup1 __FUNC_SIG(getApproved) eq getApproved jumpi + dup1 __FUNC_SIG(isApprovedForAll) eq isApprovedForAll jumpi + + dup1 __FUNC_SIG(balanceOf) eq balanceOf jumpi + dup1 __FUNC_SIG(ownerOf) eq ownerOf jumpi + + dup1 __FUNC_SIG("safeTransferFrom(address,address,uint256,bytes)") eq safeTransferFromData jumpi + + // Revert on failed dispatch + 0x00 dup1 revert + + safe_mint: + SAFE_MINT() + safe_mint_with_data: + SAFE_MINT_WITH_DATA() + + mint_jump: + MINT() + burn_jump: + BURN() + + approve: + APPROVE() + setApprovalForAll: + SET_APPROVAL_FOR_ALL() + + transferFrom: + TRANSFER_FROM() + safeTransferFrom: + SAFE_TRANSFER_FROM() + safeTransferFromData: + SAFE_TRANSFER_FROM_WITH_DATA() + + name: + NAME() + symbol: + SYMBOL() + tokenURI: + TOKEN_URI() + supportsInterface: + SUPPORTS_INTERFACE() + + getApproved: + GET_APPROVED() + isApprovedForAll: + IS_APPROVED_FOR_ALL() + + balanceOf: + BALANCE_OF() + ownerOf: + OWNER_OF() +} + + +/// @title ERC721 +/// @notice SPDX-License-Identifier: MIT +/// @author asnared +/// @author kadenzipfel +/// @notice Modern and heavily gas golfed ERC-721 implementation +/// @notice Adapted from Solmate https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC721.sol + +// Imports +#include "../utils/CommonErrors.huff" +#include "../auth/NonPayable.huff" +#include "../data-structures/Hashmap.huff" + +// Interface +#define function name() nonpayable returns (string) +#define function symbol() nonpayable returns (string) +#define function tokenURI(uint256) nonpayable returns (string) + +#define function mint(address, uint256) payable returns () +#define function burn(uint256) nonpayable returns () + +#define function transfer(address,uint256) nonpayable returns () +#define function transferFrom(address,address,uint256) nonpayable returns () +#define function safeTransferFrom(address,address,uint256) nonpayable returns () +#define function safeTransferFrom(address,address,uint256,bytes) nonpayable returns () + +#define function approve(address,uint256) nonpayable returns () +#define function setApprovalForAll(address,bool) nonpayable returns () + +#define function getApproved(uint256) view returns (address) +#define function isApprovedForAll(address,address) view returns (bool) +#define function ownerOf(uint256) view returns (address) +#define function balanceOf(address) view returns (uint256) +#define function supportsInterface(bytes4) view returns (bool) + +// Events +#define event Transfer(address,address,uint256) +#define event Approval(address,address,uint256) +#define event ApprovalForAll(address,address,bool) + +// Storage Slots +#define constant OWNER_LOCATION = FREE_STORAGE_POINTER() +#define constant BALANCE_LOCATION = FREE_STORAGE_POINTER() +#define constant SINGLE_APPROVAL_LOCATION = FREE_STORAGE_POINTER() + +// Immutables offsets +#define constant NAME_OFFSET = 0x0000000000000000000000000000000000000000000000000000000000000080 +#define constant NAME_LENGTH_OFFSET = 0x00000000000000000000000000000000000000000000000000000000000000a0 +#define constant SYMBOL_OFFSET = 0x0000000000000000000000000000000000000000000000000000000000000020 +#define constant SYMBOL_LENGTH_OFFSET = 0x0000000000000000000000000000000000000000000000000000000000000040 + +/// >>>>>>>>>>>>>>>>>>>>> CONSTRUCTOR <<<<<<<<<<<<<<<<<<<<<< /// + +/// @notice Constructor +#define macro ERC721_CONSTRUCTOR() = takes (0) returns (0) { + // Constructor arguments: + // ?, name_size, name, ?, symbol_size, symbol + + // This constructor will return the runtime bytecode with all the + // constructor arguments concatenated at the end. + + // Copy the runtime bytecode with constructor argument concatenated. + 0xb // [offset] - constructor code size + dup1 // [offset, offset] + codesize // [total_size, offset, offset] + sub // [runtime_size, offset] + dup1 // [runtime_size, runtime_size, offset] + swap2 // [offset, runtime_size, runtime_size] + returndatasize // [return_offset, offset, runtime_size, runtime_size] + codecopy // [runtime_size] + + // Return the runtime bytecode. + returndatasize // [return_offset, runtime_size] + return // [] +} + +/// >>>>>>>>>>>>>>>>>>>>> VIEW FUNCTIONS <<<<<<<<<<<<<<<<<<<<<< /// + +/// @notice Name +/// @notice Returns the token name string +#define macro NAME() = takes (0) returns (0) { + NON_PAYABLE() // [] + _GET_IMMUTABLE(NAME_OFFSET, 0x00) // [name_value] + _GET_IMMUTABLE(NAME_LENGTH_OFFSET, 0x00) // [name_length, name_value] + 0x20 0x00 mstore // [name_length, name_value] + 0x20 mstore // [name_value] + 0x40 mstore // [] + 0x60 0x00 return // [] +} + +/// @notice Symbol +/// @notice Returns the symbol of the token +#define macro SYMBOL() = takes (0) returns (0) { + NON_PAYABLE() // [] + _GET_IMMUTABLE(SYMBOL_OFFSET, 0x00) // [symbol_value] + _GET_IMMUTABLE(SYMBOL_LENGTH_OFFSET, 0x00) // [symbol_length, symbol_value] + 0x20 0x00 mstore // [symbol_length, symbol_value] + 0x20 mstore // [symbol_value] + 0x40 mstore // [] + 0x60 0x00 return // [] +} + +/// @notice Balance Of +/// @notice Returns the balance of the given address +#define macro BALANCE_OF() = takes (0) returns (0) { + NON_PAYABLE() // [] + 0x04 calldataload // [account] + [BALANCE_LOCATION] LOAD_ELEMENT_FROM_KEYS(0x00) // [balance] + 0x00 mstore // [] + 0x20 0x00 return // [] +} + +/// @notice Owner Of +/// @notice Returns the owner of the given token id +#define macro OWNER_OF() = takes (0) returns (0) { + 0x04 calldataload // [tokenId] + [OWNER_LOCATION] LOAD_ELEMENT_FROM_KEYS(0x00) // [owner] + 0x00 mstore // [] + 0x20 0x00 return // [] +} + +/// @notice Is Approved For All +/// @notice Returns whether the given operator is approved for all tokens of the given owner +#define macro IS_APPROVED_FOR_ALL() = takes (0) returns (0) { + 0x24 calldataload // [to] + 0x04 calldataload // [from, to] + LOAD_ELEMENT_FROM_KEYS(0x00) // [value] + 0x00 mstore // [] + 0x20 0x00 return // [] +} + +/// @notice Get Approved +/// @notice Returns the approved address for the given token id +#define macro GET_APPROVED() = takes (0) returns (0) { + 0x04 calldataload // [tokenId] + [SINGLE_APPROVAL_LOCATION] // [approval_slot, tokenId] + LOAD_ELEMENT_FROM_KEYS(0x00) // [spender] + 0x00 mstore // [] + 0x20 0x00 return // [] +} + +/// @notice Token URI +#define macro TOKEN_URI() = takes (0) returns (0) { + 0x20 0x00 mstore + 0x00 0x20 mstore + 0x40 0x00 return +} + +/// @notice Checks if the given interface is supported +#define macro SUPPORTS_INTERFACE() = takes (0) returns (0) { + // grab interfaceId + 0x04 calldataload // [interfaceId] + 0xe0 shr // [right_aligned_interfaceId] + + // Check if erc165 interfaceId + dup1 // [interfaceId, interfaceId] + 0x01ffc9a7 eq // [is_erc165, interfaceId] + is_interface jumpi + + // Check if erc721 interfaceId + dup1 // [interfaceId, interfaceId] + 0x80ac58cd eq // [is_erc721, interfaceId] + is_interface jumpi + + // Check if erc721Metadata interfaceId + 0x5b5e139f eq // [is_erc721Metadata] + is_interface jumpi + + // Return false (0x00) + 0x00 mstore // [] + 0x20 0x00 return // [] + + // Return true (0x01) + is_interface: + pop // [] + 0x01 0x00 mstore // [] + 0x20 0x00 return // [] +} + +/// >>>>>>>>>>>>>>>>>>>>> INTERNAL FUNCTIONS <<<<<<<<<<<<<<<<<<<<<< /// + +/// @notice Mint +/// @notice Mints a new token +/// @dev The Mint function is payable +#define macro _MINT() = takes (2) returns (0) { + // Input stack: // [to, tokenId] + // Output stack: // [] + + // Check that the recipient is valid + dup1 iszero invalid_recipient jumpi // [to, tokenId] + + // Create the minting params + 0x00 dup3 // [tokenId, from (0x00), to, tokenId] + + // Check token ownership + [OWNER_LOCATION] LOAD_ELEMENT_FROM_KEYS(0x00) // [owner, from (0x00), to, tokenId] + iszero iszero unauthorized jumpi + + // Give tokens to the recipient. + TRANSFER_GIVE_TO() // [from (0x00), to, tokenId] + + // Emit the transfer event. + __EVENT_HASH(Transfer) // [sig, from (0x00), to, tokenId] + 0x00 0x00 log4 // [] + + // Continue Executing + cont jump + + invalid_recipient: + INVALID_RECIPIENT(0x00) + + unauthorized: + ALREADY_MINTED(0x00) + + cont: +} + +/// @notice Burn +/// @notice Burns the token with the given id +#define macro _BURN() = takes (1) returns (0) { + // Input stack: // [tokenId] + NON_PAYABLE() // [tokenId] + + dup1 // [tokenId, tokenId] + [OWNER_LOCATION] LOAD_ELEMENT_FROM_KEYS(0x00) // [owner, tokenId] + + // Check that the recipient is valid + dup1 iszero // [owner == 0, owner, tokenId] + not_minted jumpi // [owner, tokenId] + + // Create the burning params + 0x00 swap1 // [owner, to (0x00), tokenId] + + // Reduce the balance of owner by 1 + 0x01 dup2 // [owner, 1, owner, to, tokenId] + [BALANCE_LOCATION] LOAD_ELEMENT_FROM_KEYS(0x00) // [balance, 1, owner, to, tokenId] + sub dup2 // [owner, balance-1, owner, to, tokenId] + [BALANCE_LOCATION] + STORE_ELEMENT_FROM_KEYS(0x00) // [owner, to, tokenId] + + // Set the owner of the token to 0x00 + 0x00 dup4 [OWNER_LOCATION] // [slot, owner, 0x00, owner, to, tokenId] + STORE_ELEMENT_FROM_KEYS(0x00) // [owner, to, tokenId] + + // Set the approval of the token to 0x00 for the owner + 0x00 dup4 [SINGLE_APPROVAL_LOCATION] // [slot, owner, 0x00, owner, to, tokenId] + STORE_ELEMENT_FROM_KEYS(0x00) // [owner, to, tokenId] + + // Emit the transfer event. + __EVENT_HASH(Transfer) // [sig, owner, to (0x00), tokenId] + 0x00 0x00 // [0, 0, sig, owner, to (0x00), tokenId] + log4 // [] + + // Continue Executing + cont jump + + not_minted: + NOT_MINTED(0x00) + + cont: +} + +/// @notice Retrives an "immutable" from the runtime bytecode. +#define macro _GET_IMMUTABLE(offset_end, free_memory) = takes (0) returns (1) { + 0x20 // [size] + codesize sub // [offset_code, size] + // [offset_memory, offset_code, size] + codecopy // [] + mload // [value] +} + +/// >>>>>>>>>>>>>>>>>>>>> EXTERNAL FUNCTIONS <<<<<<<<<<<<<<<<<<<<<< /// + +/// @notice Approve +/// @notice Approves a spender for a specific token +#define macro APPROVE() = takes (0) returns (0) { + // Load the token owner + 0x24 calldataload dup1 // [tokenId, tokenId] + [OWNER_LOCATION] + LOAD_ELEMENT_FROM_KEYS(0x00) // [owner, tokenId] + dup1 caller eq // [is_sender_owner, owner, tokenId] + + // Check if approved for all + caller dup3 // [owner, msg.sender, is_sender_owner, owner, tokenId] + LOAD_ELEMENT_FROM_KEYS(0x00) // [is_approved_for_all, is_sender_owner, owner, tokenId]] + or cont jumpi // [owner, tokenId] + not_authorized jump + cont: + + // Store approval + 0x04 calldataload dup1 dup4 // [tokenId, spender, spender, owner, tokenId] + [SINGLE_APPROVAL_LOCATION] + STORE_ELEMENT_FROM_KEYS(0x00) // [spender, owner, tokenId] + swap1 // [owner, spender, tokenId] + + // Emit the approval event + __EVENT_HASH(Approval) // [sig, owner, spender, tokenId] + 0x00 0x00 log4 // [] + + stop + + not_authorized: + UNAUTHORIZED(0x00) +} + +/// @notice Set Approval For All +/// @notice Sets an operator as approved for all tokens of the caller +#define macro SET_APPROVAL_FOR_ALL() = takes (0) returns (0) { + // Store the operator as approved for all + 0x24 calldataload // [approved] + 0x04 calldataload // [operator, approved] + caller // [msg.sender, operator, approved] + STORE_ELEMENT_FROM_KEYS(0x00) // [] + + // Emit the ApprovalForAll event + 0x24 calldataload // [approved] + 0x04 calldataload // [operator, approved] + caller // [msg.sender, operator, approved] + __EVENT_HASH(ApprovalForAll) // [sig, owner, operator] + 0x00 0x00 // [0, 32, sig, owner, operator] + log4 // [] + + // Stop execution + stop +} + +/// @notice Transfer From +/// @notice Transfers a token from one address to another +#define macro TRANSFER_FROM() = takes (0) returns (0) { + // Setup the stack for the transfer function. + 0x44 calldataload // [tokenId] + 0x24 calldataload // [to, tokenId] + 0x04 calldataload // [from, to, tokenId] + + // Accounting Logic + TRANSFER_TAKE_FROM() // [from, to, tokenId] + TRANSFER_GIVE_TO() // [from, to, tokenId] + + // Emit the transfer event + __EVENT_HASH(Transfer) // [sig,from, to, tokenId] + 0x20 0x00 log4 // [] + + // Stop execution + stop +} + +/// @notice Safe Transfer From +#define macro SAFE_TRANSFER_FROM() = takes (0) returns (0) { + // Setup the stack for the transfer function. + 0x44 calldataload // [tokenId] + 0x24 calldataload // [to, tokenId] + 0x04 calldataload // [from, to, tokenId] + + TRANSFER_TAKE_FROM() // [from, to, tokenId] + TRANSFER_GIVE_TO() // [from, to, tokenId] + + // Emit the transfer event + __EVENT_HASH(Transfer) // [sig, from, to, tokenId] + 0x00 0x00 log4 // [] + + // Make sure we can transfer to the recipient + 0x24 calldataload // [to] + dup1 extcodesize // [to.code.length, to] + iszero safe jumpi // [to] + + // onERC721Received Selector + 0x150b7a02 dup1 // [onERC721Received, onERC721Received, to] + 0xE0 shl // [onERC721Received_shifted, onERC721Received, to] + + // Store the left-shifted selector for call + 0x20 mstore // [onERC721Received, to] + + // Store the msg.sender as the first arg + caller 0x24 mstore // [onERC721Received, to] + + // Store from as the second arg + 0x04 calldataload // [from, onERC721Received, to] + 0x44 mstore // [onERC721Received, to] + + // Id is the third arg + 0x44 calldataload // [tokenId, onERC721Received, to] + 0x64 mstore // [onERC721Received, to] + + // Blank bytes array as 4th arg (no data) + 0x80 0x84 mstore + 0x00 0xA4 mstore + + // Call address(to).onERC721Received(msg.sender, from, tokenId, "") + 0x20 // [retSize, onERC721Received, to] + 0x00 // [retOffset, retSize, onERC721Received, to] + 0xA4 // [argSize, retOffset, retSize, onERC721Received, to] + dup3 // [argOffset, argSize, retOffset, retSize, onERC721Received, to] + dup3 // [value, argOffset, argSize, retOffset, retSize, onERC721Received, to] + dup7 // [to, value, argOffset, argSize, retOffset, retSize, onERC721Received, to] + gas // [gas, to, value, argOffset, argSize, retOffset, retSize, onERC721Received, to] + call // [success, onERC721Received, to] + + // Revert if call isn't successful + cont jumpi // [onERC721Received, to] + 0x00 dup1 revert + cont: + + // Compare the return data to the onERC721Received selector + 0x00 mload 0xE0 shr // [response, onERC721Received, to] + eq safe jumpi // [to] + + // Revert if the return data is not accepted + UNSAFE_RECIPIENT(0x00) + + // Stop execution if safe + safe: + stop +} + +#define macro SAFE_TRANSFER_FROM_WITH_DATA() = takes (0) returns (0) { + // Setup the stack for the transfer function. + 0x44 calldataload // [tokenId] + 0x24 calldataload // [to, tokenId] + 0x04 calldataload // [from, to, tokenId] + + TRANSFER_TAKE_FROM() // [from, to, tokenId] + TRANSFER_GIVE_TO() // [from, to, tokenId] + + // Emit the transfer event. + __EVENT_HASH(Transfer) // [sig, from, to, tokenId] + 0x00 0x00 log4 // [] + + // Make sure we can transfer to the recipient + 0x24 calldataload // [to] + dup1 extcodesize // [to.code.length, to] + iszero safe jumpi // [to] + + // onERC721Received Selector + 0x150b7a02 dup1 // [onERC721Received, onERC721Received, to] + 0xE0 shl // [onERC721Received_shifted, onERC721Received, to] + + // Store the left-shifted selector for call + 0x20 mstore // [onERC721Received, to] + + // Store the msg.sender as the first arg + caller 0x24 mstore // [onERC721Received, to] + + // Store from as the second arg + 0x04 calldataload // [from, onERC721Received, to] + 0x44 mstore // [onERC721Received, to] + + // Id is the third arg + 0x44 calldataload // [tokenId, onERC721Received, to] + 0x64 mstore // [onERC721Received, to] + + 0x84 calldataload // [len(data), onERC721Received, to] + 0x05 shl // [len(data) * 0x20, onERC721Received, to] + 0x40 add // [len(data) * 0x20 + 0x40, onERC721Received, to] + dup1 // [len(data) * 0x20 + 0x40, len(data) * 0x20 + 0x40, onERC721received, to] + 0x64 // [0x64, len(data) * 0x20 + 0x40, len(data) * 0x20 + 0x40, onERC721received, to] + 0x84 // [0x20, 0x64, len(data) * 0x20 + 0x40, len(data) * 0x20 + 0x40, onERC721received, to] + calldatacopy // [len(bytes), onERC721received, to] + + // Call address(to).onERC721Received(msg.sender, from, tokenId, bytes) + 0x20 // [retSize, len(bytes), onERC721Received, to] + 0x00 // [retOffset, retSize, len(bytes), onERC721Received, to] + swap1 swap2 // [len(bytes), retOffset, retSize, onERC721Received, to] + 0x64 add // [argSize, retOffset, retSize, onERC721Received, to] + dup3 // [argOffset, argSize, retOffset, retSize, len(bytes), onERC721Received, to] + dup3 // [value, argOffset, argSize, retOffset, retSize, len(bytes), onERC721Received, to] + dup7 // [to, value, argOffset, argSize, retOffset, retSize, len(bytes), onERC721Received, to] + gas // [gas, to, value, argOffset, argSize, retOffset, retSize, len(bytes), onERC721Received, to] + call // [success, len(bytes), onERC721Received, to] + + // Revert if call isn't successful + cont jumpi // [len(bytes), onERC721Received, to] + 0x00 dup1 revert + cont: + + // Compare the return data to the onERC721Received selector + 0x00 mload 0xE0 shr // [response, onERC721Received, to] + eq safe jumpi // [to] + + // Revert if the return data is not accepted + UNSAFE_RECIPIENT(0x00) + + // Stop execution if safe + safe: + stop +} + +/// >>>>>>>>>>>>>>>>>>>>> INTERNAL HELPERS <<<<<<<<<<<<<<<<<<<<<< /// + +/// @notice Internal Macro to update Transfer from accounting +#define macro TRANSFER_TAKE_FROM() = takes (3) returns (3) { + // Input stack: [from, to, tokenId] + + // If from !== ownerOf[tokenId] revert with "WRONG_FROM" + dup1 dup4 // [tokenId, from, from, to, tokenId] + [OWNER_LOCATION] LOAD_ELEMENT_FROM_KEYS(0x00) // [owner, from, from, to, tokenId] + eq cont jumpi // [from, to, tokenId] + WRONG_FROM(0x00) + cont: + + // If to === address(0) revert with "INVALID_RECIPIENT" + dup2 iszero iszero continue jumpi // [from, to, tokenId] + INVALID_RECIPIENT(0x00) + continue: + + // Check if msg.sender == from + dup1 caller eq // [msg.sender == from, from, to, tokenId] + is_authorized jumpi // [from, to, tokenId] + + // Check if approved for all + caller dup2 // [from, msg.sender, from, to, tokenId] + LOAD_ELEMENT_FROM_KEYS(0x00) // [is_approved_for_all, from, to, tokenId] + is_authorized jumpi // [from, to, tokenId] + + // Check if approved for tokenId + dup3 // [tokenId, from, to, tokenId] + [SINGLE_APPROVAL_LOCATION] // [SINGLE_APPROVAL_LOCATION, tokenId, from, to, tokenId] + LOAD_ELEMENT_FROM_KEYS(0x00) // [address_approved_for_tokenId, from, to, tokenId] + caller eq is_authorized jumpi // [from, to, tokenId] + + // If msg.sender != from && !isApprovedForAll[from][msg.sender] && msg.sender != getApproved[id], + UNAUTHORIZED(0x00) + + is_authorized: + + // Update balance of from + 0x01 dup2 // [from, 1, from, to, tokenId] + [BALANCE_LOCATION] LOAD_ELEMENT_FROM_KEYS(0x00) // [balance, 1, from, to, tokenId] + sub dup2 // [from, balance-1, from, to, tokenId] + [BALANCE_LOCATION] + STORE_ELEMENT_FROM_KEYS(0x00) // [from, to, tokenId] +} + +/// @notice Internal Macro to update Transfer to accounting +#define macro TRANSFER_GIVE_TO() = takes (3) returns (3) { + // retrieve balance + // input stack: // [from, to, tokenId] + dup2 // [to, from, to, tokenId] + [BALANCE_LOCATION] // [balance_slot, to, from, to, tokenId] + LOAD_ELEMENT_FROM_KEYS(0x00) // [balance, from, to, tokenId] + 0x01 add // [balance+1, from, to, tokenId] + + // update balance + dup3 // [to, balance+1, from, to, tokenId] + [BALANCE_LOCATION] // [balance_slot, to, balance+1, from, to, tokenId] + STORE_ELEMENT_FROM_KEYS(0x00) // [from, to, tokenId] + + // update ownerOf + dup2 dup4 // [tokenId, to, from, to, tokenId] + [OWNER_LOCATION] // [owner_slot, tokenId, to, from, to, tokenId] + STORE_ELEMENT_FROM_KEYS(0x00) // [from, to, tokenId] + + // update approval + 0x00 dup4 // [tokenId, address(0), from, to, tokenId] + [SINGLE_APPROVAL_LOCATION] // [approval_slot, tokenId, address(0), from, to, tokenId] + STORE_ELEMENT_FROM_KEYS(0x00) // [from, to, tokenId] +} diff --git a/src/tokens/__TEMP__tdpvmgiyjorautmnplhzvgjsaeubpvhbERC4626.huff b/src/tokens/__TEMP__tdpvmgiyjorautmnplhzvgjsaeubpvhbERC4626.huff new file mode 100644 index 00000000..5e3a3cbb --- /dev/null +++ b/src/tokens/__TEMP__tdpvmgiyjorautmnplhzvgjsaeubpvhbERC4626.huff @@ -0,0 +1,859 @@ + +#define function beforeWithdrawHookCalledCounter() nonpayable returns (uint256) +#define function afterDepositHookCalledCounter() nonpayable returns (uint256) + +#define constant BEFORE_HOOK_COUNTER = FREE_STORAGE_POINTER() +#define constant AFTER_HOOK_COUNTER = FREE_STORAGE_POINTER() + +#define macro CONSTRUCTOR() = takes (0) returns (0) { + ERC4626_CONSTRUCTOR() // [] +} + +#define macro BEFORE_WITHDRAW() = takes (2) returns (0) { + // Input Stack: [assets, shares] + // Output Stack: [] + pop pop // [] + [BEFORE_HOOK_COUNTER] sload // [counter] + 0x01 add // [counter + 1] + [BEFORE_HOOK_COUNTER] sstore // [] +} + +#define macro AFTER_DEPOSIT() = takes (2) returns (0) { + // Input Stack: [assets, shares] + // Output Stack: [] + pop pop // [] + [AFTER_HOOK_COUNTER] sload // [counter] + 0x01 add // [counter + 1] + [AFTER_HOOK_COUNTER] sstore // [] +} + +#define macro READ_BEFORE_HOOK_COUNTER() = takes (0) returns (0) { + [BEFORE_HOOK_COUNTER] sload // [counter] + 0x00 mstore // [] + 0x20 0x00 return // [] +} + +#define macro READ_AFTER_HOOK_COUNTER() = takes (0) returns (0) { + [AFTER_HOOK_COUNTER] sload // [counter] + 0x00 mstore // [] + 0x20 0x00 return // [] +} + +#define macro TOTAL_ASSETS_INNER() = takes (0) returns (1) { + // Input Stack: [] + // Output Stack: [total_assets] + + // Store the asset.balanceOf(address(this)) args in memory + __FUNC_SIG(balanceOf) + 0xE0 shl + 0x20 mstore + address 0x24 mstore + + // Get the asset variable + _GET_IMMUTABLE(ASSET_OFFSET, 0x80) // [asset] + + // Construct the call + 0x20 // [retSize, asset] + 0x00 // [retOffset, retSize, asset] + 0x24 // [argSize, retOffset, retSize, asset] + 0x20 // [argOffset, argSize, retOffset, retSize, asset] + 0x00 // [value, argOffset, argSize, retOffset, retSize, asset] + dup6 // [to, value, argOffset, argSize, retOffset, retSize, asset] + gas // [gas, to, value, argOffset, argSize, retOffset, retSize, asset] + call // [success, asset] + + // Verify the call succeeded + iszero iszero success jumpi // [asset] + 0x00 dup1 revert // [] + success: + + // Since the returndata is copied to [0x00:0x20], we can just mload + pop 0x00 mload // [total_assets] +} + + +#define macro MAIN() = takes (0) returns (0) { + pc calldataload 0xE0 shr // [sig] + + dup1 __FUNC_SIG(beforeWithdrawHookCalledCounter) eq before_jump jumpi // [sig] + dup1 __FUNC_SIG(afterDepositHookCalledCounter) eq after_jump jumpi // [sig] + + ERC4626_MAIN() // [sig] + + 0x00 dup1 revert + + before_jump: + READ_BEFORE_HOOK_COUNTER() + after_jump: + READ_AFTER_HOOK_COUNTER() +} + + +/// @title ERC4626 +/// @notice SPDX-License-Identifier: MIT +/// @author asnared +/// @notice Minimal ERC4626 tokenized Vault implementation. +/// @notice Adapted from Solmate (https://github.com/transmissions11/solmate/blob/main/src/mixins/ERC4626.sol) + +// ERC4626 is ERC20 +#include "./ERC20.huff" +#include "../utils/CommonErrors.huff" +#include "../math/FixedPointMath.huff" + +// Events +#define event Deposit(address indexed caller, address indexed owner, uint256 assets, uint256 shares) +#define event Withdraw(address indexed caller, address indexed receiver, address indexed owner, uint256 assets, uint256 shares) + +// Interface +#define function asset() view returns (address) + +#define function deposit(uint256 assets, address receiver) payable returns (uint256 shares) +#define function withdraw(uint256 assets, address receiver, address owner) payable returns (uint256 shares) +#define function mint(uint256 shares, address receiver) payable returns (uint256 assets) +#define function redeem(uint256 shares, address receiver, address owner) payable returns (uint256 assets) + +#define function totalAssets() view returns (uint256) +#define function convertToShares(uint256 assets) view returns (uint256) +#define function convertToAssets(uint256 shares) view returns (uint256) +#define function previewDeposit(uint256 assets) view returns (uint256) +#define function previewMint(uint256 shares) view returns (uint256) +#define function previewWithdraw(uint256 assets) view returns (uint256) +#define function previewRedeem(uint256 shares) view returns (uint256) + +#define function maxDeposit(address) view returns (uint256) +#define function maxMint(address) view returns (uint256) +#define function maxWithdraw(address owner) view returns (uint256) +#define function maxRedeem(address owner) view returns (uint256) + +// Immutables offsets +#define constant ASSET_OFFSET = 0x0000000000000000000000000000000000000000000000000000000000000100 + +#define constant TYPE_UINT_256_MAX = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + +/// @notice Constructor +#define macro ERC4626_CONSTRUCTOR() = takes (0) returns (0) { + // Copy the asset address into memory and then the stack from the bytecode + 0x20 // [size] - byte size to copy + 0x20 [ASSET_OFFSET] sub // [asset_offset_now, size] + codesize sub // [offset, size] - offset in the code to copy from + 0x00 // [mem, offset, size] - offset in memory to copy to + codecopy // [] - stores asset at 0x00 + + // Store the decimals function selector in memory to call + __FUNC_SIG(decimals) // [sig_right_padded] + 0xE0 shl // [sig_left_padded] + 0x20 mstore // [] + + // Call the asset to get its decimals + 0x20 // [retSize] + 0x00 // [retOffset, retSize] + 0x04 // [argSize, retOffset, retSize] + 0x20 // [argOffset, argSize, retOffset, retSize] + 0x00 mload // [to, argOffset, argSize, retOffset, retSize] + gas // [gas, to, argOffset, argSize, retOffset, retSize] + staticcall // [success] + + // If the call failed, revert + cont jumpi // [] + 0x00 dup1 revert // [] + cont: + + // Load the decimals + 0x00 mload // [decimals] + + // Configure the initial domain separator + chainid [INITIAL_CHAIN_ID] sstore // [decimals] + COMPUTE_DOMAIN_SEPARATOR() // [DOMAIN_SEPARATOR, decimals] + [INITIAL_DOMAIN_SEPARATOR] sstore // [decimals] + + // Copy the runtime bytecode with constructor argument concatenated. + __codesize(CONSTRUCTOR) // [offset, decimals] + dup1 // [offset, offset, decimals] + codesize // [total_size, offset, offset, decimals] + sub // [runtime_size, offset, decimals] + dup1 // [runtime_size, runtime_size, offset, decimals] + swap2 // [offset, runtime_size, runtime_size, decimals] + returndatasize // [return_offset, offset, runtime_size, runtime_size, decimals] + codecopy // [runtime_size, decimals] + + // Add the decimals at the of the bytecode. + swap1 // [decimals, runtime_size] + dup2 // [runtime_size, decimals, runtime_size] + returndatasize add mstore // [runtime_size] + + // Return the runtime bytecode. + 0x20 add // [new_runtime_size] + returndatasize // [return_offset, new_runtime_size] + return // [] +} + +/// @notice Returns the ERC4626 decimals +#define macro ERC4626_DECIMALS() = takes (0) returns (0) { + _GET_IMMUTABLE(DECIMALS_OFFSET, 0x00) // [decimals] + 0x00 mstore // [] + 0x20 0x00 return // [] +} + +/// @notice Returns the ERC4626 asset +#define macro ERC4626_ASSET() = takes (0) returns (0) { + _GET_IMMUTABLE(ASSET_OFFSET, 0x00) // [asset] + 0x00 mstore // [] + 0x20 0x00 return // [] +} + +// ------------------------------------------------------ +// DEPOSIT/WITHDRAWAL LOGIC +// ------------------------------------------------------ + +/// @notice Mint +/// @notice Mints a {receiver} x amount of {assets} proportional to the input {shares} +/// @param {shares} [uint256] The amount of shares to mint +#define macro ERC4626_MINT() = takes (0) returns (0) { + 0x24 calldataload // [receiver] + 0x04 calldataload // [shares, receiver] + MINT_INNER() // [assets] + 0x00 mstore // [] + 0x20 0x00 return // [] +} + +/// @notice Mint Internal Helper +#define macro MINT_INNER() = takes (2) returns (1) { + // Input stack: [shares, receiver] + // Output stack: [assets] + + // Preview the mint given the number of shares + dup1 // [shares, shares, receiver] + PREVIEW_MINT_INNER() // [assets, shares, receiver] + + // Transfer the assets from the caller to the vault + + // Store the transferFrom selector in memory + __FUNC_SIG(transferFrom) // [selector, assets, shares, receiver] + 0xE0 shl // [selector, assets, shares, receiver] + 0x00 mstore // [assets, shares, receiver] + + // Store the caller in memory as the first arg + caller 0x04 mstore // [assets, shares, receiver] + + // Store this address as the second call argument in memory + address 0x24 mstore // [assets, shares, receiver] + + // Store assets as the third call argument in memory + dup1 0x44 mstore // [assets, shares, receiver] + + // Load the asset as the call destination + _GET_IMMUTABLE(ASSET_OFFSET, 0x80) // [asset, assets, shares, receiver] + + // Construct the call + 0x00 // [retSize, asset, assets, shares, receiver] + 0x00 // [retOffset, retSize, asset, assets, shares, receiver] + 0x64 // [argSize, retOffset, retSize, asset, assets, shares, receiver] + 0x00 // [argOffset, argSize, retOffset, retSize, asset, assets, shares, receiver] + 0x00 // [value, argOffset, argSize, retOffset, retSize, asset, assets, shares, receiver] + dup6 // [to, value, argOffset, argSize, retOffset, retSize, asset, assets, shares, receiver] + gas // [gas, to, value, argOffset, argSize, retOffset, retSize, asset, assets, shares, receiver] + call // [success, asset, assets, shares, receiver] + + // Verify the call succeeded + success jumpi // [asset, assets, shares, receiver] + 0x00 dup1 revert // [] + success: + + // Mint vault shares to the receiver + pop // [assets, shares, receiver] + dup3 dup3 // [shares, receiver, assets, shares, receiver] + _MINT() // [assets, shares, receiver] + + // Emit the deposit event + dup1 0x00 mstore // [assets, shares, receiver] + dup2 0x20 mstore // [assets, shares, receiver] + dup3 caller // [msg.sender, receiver, assets, shares, receiver] + __EVENT_HASH(Deposit) // [event_hash, msg.sender, receiver, assets, shares, receiver] + 0x40 0x00 log3 // [assets, shares, receiver] + + // Call the after deposit hook + swap1 dup2 // [assets, shares, assets, receiver] + AFTER_DEPOSIT() // [assets, receiver] + + // Return just the assets + swap1 pop // [assets] +} + +/// @notice Redeem +/// @notice Redeems a {receiver} x amount of {assets} proportional to the input {shares} +/// @param {shares} [uint256] The amount of shares to redeem +/// @param {receiver} [address] The address to receive the assets +/// @param {owner} [address] The address that owns the shares +#define macro ERC4626_REDEEM() = takes (0) returns (0) { + 0x44 calldataload // [owner] + 0x24 calldataload // [receiver, owner] + 0x04 calldataload // [shares, receiver, owner] + REDEEM_INNER() // [assets] + 0x00 mstore // [] + 0x20 0x00 return // [] +} + +/// @notice Redeem Internal Helper +#define macro REDEEM_INNER() = takes (3) returns (1) { + // Input stack: [shares, receiver, owner] + // Output stack: [assets] + + // Jump ahead if msg.sender == owner + dup3 caller eq ahead jumpi // [shares, receiver, owner] + + // Check if the caller is approved to redeem the shares + + // Get the allowance[owner][msg.sender] + caller dup4 // [owner, msg.sender, shares, receiver, owner] + [APPROVAL_SLOT] // [slot, owner, msg.sender, shares, receiver, owner] + LOAD_ELEMENT_FROM_KEYS_2D(0x00) // [allowance, shares, receiver, owner] + + // If the allowed is no infinite approval, set to the allowance less shares + dup1 [TYPE_UINT_256_MAX] // [type(uint256).max, allowance, allowance, shares, receiver, owner] + eq infinite jumpi // [allowance, shares, receiver, owner] + + // Set the new allowance + dup2 dup2 sub // [new_allowance, allowance, shares, receiver, owner] + caller dup6 [APPROVAL_SLOT] // [slot, owner, msg.sender, new_allowance, allowance, shares, receiver, owner] + STORE_ELEMENT_FROM_KEYS_2D(0x00) // [allowance, shares, receiver, owner] + + // Jump dests for initial checks + infinite: + pop // [shares, receiver, owner] + ahead: + + // Validate that the assets are non-zero + dup1 CONVERT_TO_ASSETS_INNER() // [assets, shares, receiver, owner] + dup1 non_zero jumpi // [assets, shares, receiver, owner] + ZERO_ASSETS(0x00) + non_zero: + + // Call the before withdraw hook + dup2 dup2 BEFORE_WITHDRAW() // [assets, shares, receiver, owner] + + // Burn the shares, input stack: [shares, owner] + dup4 dup3 _BURN() // [assets, shares, receiver, owner] + + // Emit the withdraw event + dup1 0x00 mstore // [assets, shares, receiver, owner] + dup2 0x20 mstore // [assets, shares, receiver, owner] + dup4 dup4 caller // [msg.sender, receiver, owner, assets, shares, receiver, owner] + __EVENT_HASH(Withdraw) // [event_hash, msg.sender, receiver, owner, assets, shares, receiver, owner] + 0x40 0x00 log4 // [assets, shares, receiver, owner] + + // Transfer the assets from the receiver to the vault + // Store the transfer selector in memory + __FUNC_SIG(transfer) // [selector, assets, shares, receiver, owner] + 0xE0 shl // [selector, assets, shares, receiver, owner] + 0x00 mstore // [assets, shares, receiver, owner] + + // Store the receiver in memory as the first arg + dup3 0x04 mstore // [assets, shares, receiver, owner] + + // Store the assets as the second call argument in memory + dup1 0x24 mstore // [assets, shares, receiver, owner] + + // Load the asset as the call destination + _GET_IMMUTABLE(ASSET_OFFSET, 0x80) // [asset, assets, shares, receiver, owner] + // [ADDRESS] + + // Construct the call + 0x00 // [retSize, asset, assets, shares, receiver, owner] + 0x00 // [retOffset, retSize, asset, assets, shares, receiver, owner] + 0x44 // [argSize, retOffset, retSize, asset, assets, shares, receiver, owner] + 0x00 // [argOffset, argSize, retOffset, retSize, asset, assets, shares, receiver, owner] + 0x00 // [value, argOffset, argSize, retOffset, retSize, asset, assets, shares, receiver, owner] + dup6 // [to, value, argOffset, argSize, retOffset, retSize, asset, assets, shares, receiver, owner] + gas // [gas, to, value, argOffset, argSize, retOffset, retSize, asset, assets, shares, receiver, owner] + call // [success, asset, assets, shares, receiver, owner] + + // Verify the call succeeded + success jumpi // [asset, assets, shares, receiver, owner] + 0x00 dup1 revert // [] + success: + + // Clean the stack and return the assets + pop swap4 pop pop pop // [assets] +} + +/// @notice Deposit +/// @notice Deposits the asset in exchange for shares +/// @param {assets} [uint256] The amount of assets to deposit +/// @param {receiver} [address] The address to receive the shares +#define macro ERC4626_DEPOSIT() = takes (0) returns (0) { + 0x24 calldataload // [receiver] + 0x04 calldataload // [assets, receiver] + DEPOSIT_INNER() // [shares] + 0x00 mstore // [] + 0x20 0x00 return // [] +} + +/// @notice Deposit assets into the ERC4626 Vault +#define macro DEPOSIT_INNER() = takes (2) returns (1) { + // Input stack: [assets, receiver] + // Output stack: [shares] + + // Validate that the assets shares are not zero + dup1 // [assets, assets, receiver] + PREVIEW_DEPOSIT_INNER() // [shares, assets, receiver] + dup1 cont jumpi // [shares, assets, receiver] + ZERO_SHARES(0x00) + cont: + + // Store the transferFrom selector in memory + __FUNC_SIG(transferFrom) // [selector, shares, assets, receiver] + 0xE0 shl // [selector, shares, assets, receiver] + 0x00 mstore // [shares, assets, receiver] + + // Store the caller in memory as the first arg + caller 0x04 mstore // [shares, assets, receiver] + + // Store this address as the second call argument in memory + address 0x24 mstore // [shares, assets, receiver] + + // Store assets as the third call argument in memory + dup2 0x44 mstore // [shares, assets, receiver] + + // Load the asset + _GET_IMMUTABLE(ASSET_OFFSET, 0x80) // [asset, shares, assets, receiver] + + // Construct the call + 0x00 // [retSize, asset, shares, assets, receiver] + 0x00 // [retOffset, retSize, asset, shares, assets, receiver] + 0x64 // [argSize, retOffset, retSize, asset, shares, assets, receiver] + 0x00 // [argOffset, argSize, retOffset, retSize, asset, shares, assets, receiver] + 0x00 // [value, argOffset, argSize, retOffset, retSize, asset, shares, assets, receiver] + dup6 // [to, value, argOffset, argSize, retOffset, retSize, asset, shares, assets, receiver] + gas // [gas, to, value, argOffset, argSize, retOffset, retSize, asset, shares, assets, receiver] + call // [success, asset, shares, assets, receiver] + + // Verify the call succeeded + success jumpi // [asset, shares, assets, receiver] + 0x00 dup1 revert // [] + success: + + // Mint to the receiver + pop dup3 dup2 // [shares, receiver, shares, assets, receiver] + + _MINT() // [shares, assets, receiver] + + // Emit the Deposit Event + dup2 0x00 mstore // [shares, assets, receiver] + dup1 0x20 mstore // [shares, assets, receiver] + dup3 caller // [msg.sender, receiver, shares, assets, receiver] + __EVENT_HASH(Deposit) // [event_hash, msg.sender, receiver, shares, assets, receiver] + 0x40 0x00 log3 // [shares, assets, receiver] + + // Call the after deposit hook + dup1 swap2 swap1 // [shares, assets, shares, receiver] + AFTER_DEPOSIT() // [shares, receiver] + + // Return the shares + swap1 pop // [shares] +} + +/// @notice Withdraw +/// @notice Withdraws the shares in exchange for the underlying assets +/// @param {assets} [uint256] The amount of shares to withdraw +/// @param {receiver} [address] The address to receive the assets +/// @param {owner} [address] The address that owns the shares +#define macro ERC4626_WITHDRAW() = takes (0) returns (0) { + 0x44 calldataload // [owner] + 0x24 calldataload // [receiver, owner] + 0x04 calldataload // [assets, receiver, owner] + WITHDRAWAL_INNER() // [shares] + 0x00 mstore // [] + 0x20 0x00 return // [] +} + +/// @notice Withdraws assets from an ERC4626 Vault +#define macro WITHDRAWAL_INNER() = takes (3) returns (1) { + // Input stack: [assets, receiver, owner] + // Output stack: [shares] + + // Get the shares from the assets + dup1 PREVIEW_WITHDRAW_INNER() // [shares, assets, receiver, owner] + + // Skip ahead if msg.sender is the owner + dup4 caller eq owner_jump jumpi // [shares, assets, receiver, owner] + + // Get the allowance[owner][msg.sender] + caller dup5 // [owner, msg.sender, shares, assets, receiver, owner] + [APPROVAL_SLOT] // [slot, owner, msg.sender, shares, assets, receiver, owner] + LOAD_ELEMENT_FROM_KEYS_2D(0x00) // [allowance, shares, assets, receiver, owner] + + // If the allowed is no infinite approval, set to the allowance less shares + dup1 [TYPE_UINT_256_MAX] // [type(uint256).max, allowance, allowance, shares, assets, receiver, owner] + eq infinite jumpi // [allowance, shares, assets, receiver, owner] + + // Set the new allowance + dup2 dup2 sub // [new_allowance, allowance, shares, assets, receiver, owner] + caller dup6 [APPROVAL_SLOT] // [slot, owner, msg.sender, new_allowance, allowance, shares, assets, receiver, owner] + STORE_ELEMENT_FROM_KEYS_2D(0x00) // [allowance, shares, assets, receiver, owner] + + infinite: + pop // [shares, assets, receiver, owner] + + owner_jump: + + // Call the before withdrawal hook + dup1 dup3 // [assets, shares, shares, assets, receiver, owner] + BEFORE_WITHDRAW() // [shares, assets, receiver, owner] + + // Burn the shares + dup4 dup2 // [shares, owner, shares, assets, receiver, owner] + _BURN() // [shares, assets, receiver, owner] + + // Emit the Withdraw Event + dup2 0x00 mstore // [shares, assets, receiver, owner] + dup1 0x20 mstore // [shares, assets, receiver, owner] + dup4 dup3 caller // [msg.sender, assets, owner, shares, assets, receiver, owner] + __EVENT_HASH(Withdraw) // [event_hash, msg.sender, assets, owner, shares, assets, receiver, owner] + 0x40 0x00 log4 // [shares, assets, receiver, owner] + + // Store the transfer selector in memory + __FUNC_SIG(transfer) // [selector, shares, assets, receiver, owner] + 0xE0 shl // [selector, shares, assets, receiver, owner] + 0x00 mstore // [shares, assets, receiver, owner] + + // Store the receiver in memory as the first arg + dup3 0x04 mstore // [shares, assets, receiver, owner] + + // Store this address as the second call argument in memory + dup2 0x24 mstore // [shares, assets, receiver, owner] + + // Load asset from storage + _GET_IMMUTABLE(ASSET_OFFSET, 0x80) // [asset, shares, assets, receiver, owner] + + // Construct the call + 0x00 // [retSize, asset, shares, assets, receiver, owner] + 0x00 // [retOffset, retSize, asset, shares, assets, receiver, owner] + 0x44 // [argSize, retOffset, retSize, asset, shares, assets, receiver, owner] + 0x00 // [argOffset, argSize, retOffset, retSize, asset, shares, assets, receiver, owner] + 0x00 // [value, argOffset, argSize, retOffset, retSize, asset, shares, assets, receiver, owner] + dup6 // [to, value, argOffset, argSize, retOffset, retSize, asset, shares, assets, receiver, owner] + gas // [gas, to, value, argOffset, argSize, retOffset, retSize, asset, shares, assets, receiver, owner] + call // [success, asset, shares, assets, receiver, owner] + + // Verify the call succeeded + success jumpi // [asset, shares, assets, receiver, owner] + 0x00 dup1 revert // [] + success: + + // Return shares + pop // [shares, assets, receiver, owner] + swap3 pop pop pop // [shares] +} + + +// ------------------------------------------------------ +// ACCOUNTING LOGIC +// ------------------------------------------------------ + +// Input Stack: [] +// Output Stack: [total_assets] +/// @notice Returns the total amount of assets in the Vault +/// @notice REQUIRES OVERRIDEN IMPLEMENTATION +// #define macro TOTAL_ASSETS_INNER() = takes (0) returns (1) + +/// @notice Returns the total amount of assets in the Vault +#define macro TOTAL_ASSETS() = takes (0) returns (0) { + TOTAL_ASSETS_INNER() // [total_assets] + 0x00 mstore // [] + 0x20 0x00 return // [] +} + +/// @notice Returns the amount of assets needed to mint the given amount of shares +/// @param {shares} [uint256] The amount of shares to mint +#define macro PREVIEW_MINT() = takes (0) returns (0) { + 0x04 calldataload // [shares] + PREVIEW_MINT_INNER() // [assets] + 0x00 mstore // [] + 0x20 0x00 return // [] +} + +#define macro PREVIEW_MINT_INNER() = takes (1) returns (1) { + // Input Stack: [shares] + // Output Stack: [assets] + + // Load the total supply + [TOTAL_SUPPLY_SLOT] sload // [supply, shares] + + // Return shares if supply is zero + dup1 calculate jumpi // [supply, shares] + pop cont jump // [] + + // Otherwise mul div up + calculate: + + swap1 // [shares, supply] + TOTAL_ASSETS_INNER() swap1 // [shares, total_assets, supply] + MUL_DIV_UP(fail) // [shares] + cont jump + + // Fail with an arithmetic overflow + fail: + [ARITHMETIC_OVERFLOW] PANIC() + + // Resume withdrawal with share count + cont: // [assets] +} + +/// @notice Calculates the amount of shares that would be exchanged for a given amount of assets +/// @param {assets} [uint256] The amount of assets to exchange +#define macro PREVIEW_DEPOSIT() = takes (1) returns (1) { + 0x04 calldataload // [assets] + PREVIEW_DEPOSIT_INNER() // [shares] + 0x00 mstore // [] + 0x20 0x00 return // [] +} + +#define macro PREVIEW_DEPOSIT_INNER() = takes (1) returns (1) { + CONVERT_TO_SHARES_INNER() // [shares] +} + +/// @notice Converts assets to shares +/// @param {assets} [uint256] The amount of assets to convert +#define macro CONVERT_TO_SHARES() = takes (0) returns (0) { + 0x04 calldataload // [assets] + CONVERT_TO_SHARES_INNER() // [shares] + 0x00 mstore // [] + 0x20 0x00 return // [] +} + +#define macro CONVERT_TO_SHARES_INNER() = takes (1) returns (1) { + // Input Stack: [assets] + // Output Stack: [shares] + + [TOTAL_SUPPLY_SLOT] sload // [supply, assets] + + // Return assets if supply is zero + dup1 calculate jumpi // [supply, assets] + pop cont jump // [] + + // Otherwise mul div down + calculate: + + TOTAL_ASSETS_INNER() swap2 // [assets, supply, total_assets] + MUL_DIV_DOWN(fail) // [shares] + cont jump + + // Fail with an arithmetic overflow + fail: + [ARITHMETIC_OVERFLOW] PANIC() + + // Resume withdrawal with share count + cont: // [shares] +} + +/// @notice Converts shares to assets +/// @param {shares} [uint256] The amount of shares to convert +#define macro CONVERT_TO_ASSETS() = takes (0) returns (0) { + 0x04 calldataload // [shares] + CONVERT_TO_ASSETS_INNER() // [assets] + 0x00 mstore // [] + 0x20 0x00 return // [] +} + +#define macro CONVERT_TO_ASSETS_INNER() = takes (1) returns (1) { + // Input Stack: [shares] + // Output Stack: [assets] + + [TOTAL_SUPPLY_SLOT] sload // [supply, shares] + + // Return assets if supply is zero + dup1 calculate jumpi // [supply, shares] + pop cont jump // [] + + // Otherwise mul div down + calculate: + + swap1 // [shares, supply] + TOTAL_ASSETS_INNER() swap1 // [shares, total_assets, supply] + MUL_DIV_DOWN(fail) // [assets] + cont jump + + // Fail with an arithmetic overflow + fail: + [ARITHMETIC_OVERFLOW] PANIC() + + // Resume withdrawal with share count + cont: // [assets] +} + +/// @notice Calculates the amount of shares that would be exchanged for a given amount of assets +/// @param {assets} [uint256] The amount of assets to exchange +#define macro PREVIEW_WITHDRAW() = takes (1) returns (1) { + 0x04 calldataload // [assets] + PREVIEW_WITHDRAW_INNER() // [shares] + 0x00 mstore // [] + 0x20 0x00 return // [] +} + +#define macro PREVIEW_WITHDRAW_INNER() = takes (1) returns (1) { + // Input Stack: [assets] + // Output Stack: [shares] + + [TOTAL_SUPPLY_SLOT] sload // [supply, assets] + + // Return assets if supply is zero + dup1 calculate jumpi // [supply, assets] + pop dont_fail jump // [] + + // Otherwise mul div up + calculate: + + TOTAL_ASSETS_INNER() swap2 // [assets, supply, total_assets] + MUL_DIV_UP(fail) // [shares] + dont_fail jump + + // Fail with an arithmetic overflow + fail: + [ARITHMETIC_OVERFLOW] PANIC() + + // Resume withdrawal with share count + dont_fail: // [shares] +} + +/// @notice Calculates the amount of assets that would be exchanged for a given amount of shares on redemption +/// @param {shares} [uint256] The amount of shares to exchange +#define macro PREVIEW_REDEEM() = takes (0) returns (0) { + 0x04 calldataload // [shares] + CONVERT_TO_ASSETS_INNER() // [assets] + 0x00 mstore // [] + 0x20 0x00 return // [] +} + +// ------------------------------------------------------ +// DEPOSIT/WITHDRAWAL LIMIT LOGIC +// ------------------------------------------------------ + +/// @notice Max Deposit +/// @notice Returns the maximum amount of assets available to deposit +#define macro MAX_DEPOSIT() = takes (0) returns (0) { + [TYPE_UINT_256_MAX] // [type(uint256).max] + 0x00 mstore // [] + 0x20 0x00 return // [] +} + +/// @notice Max Mint +/// @notice Returns the maximum amount of shares available to mint +#define macro MAX_MINT() = takes (0) returns (0) { + [TYPE_UINT_256_MAX] // [type(uint256).max] + 0x00 mstore // [] + 0x20 0x00 return // [] +} + +/// @notice Max Withdraw +/// @notice Returns the maximum amount of assets available to withdraw +/// @param {owner} [address] The address of the account to withdraw assets from +#define macro MAX_WITHDRAW() = takes (0) returns (0) { + 0x04 calldataload // [owner] + [BALANCE_SLOT] sload // [balanceOf[owner]] + CONVERT_TO_ASSETS_INNER() // [assets] + 0x00 mstore // [] + 0x20 0x00 return // [] +} + +/// @notice Max Redeem +/// @notice Returns the maximum amount of shares available to redeem +/// @param {owner} [address] The address of the account to redeem shares from +#define macro MAX_REDEEM() = takes (0) returns (0) { + 0x04 calldataload // [owner] + [BALANCE_SLOT] sload // [balanceOf[owner]] + 0x00 mstore // [] + 0x20 0x00 return // [] +} + +// ------------------------------------------------------ +// INTERNAL HOOKS LOGIC +// ------------------------------------------------------ + +// Input Stack: [assets, shares] +// Output Stack: [] +/// @notice Called before a withdrawal +/// @notice REQUIRES OVERRIDEN IMPLEMENTATION +// #define macro BEFORE_WITHDRAW() = takes (2) returns (0) + +// Input Stack: [assets, shares] +// Output Stack: [] +/// @notice Called after a deposit +/// @notice REQUIRES OVERRIDEN IMPLEMENTATION +// #define macro AFTER_DEPOSIT() = takes (2) returns (0) + +// ------------------------------------------------------ +// DISPATCH LOGIC +// ------------------------------------------------------ + +/// @notice An internal function dispatcher +#define macro ERC4626_MAIN() = takes (1) returns (1) { + // Input stack: [func_selector] + // Output stack: [func_selector] + + dup1 __FUNC_SIG(decimals) eq decimals_jump jumpi // [func_selector] + dup1 __FUNC_SIG(asset) eq asset_jump jumpi // [func_selector] + + dup1 __FUNC_SIG(deposit) eq deposit_jump jumpi // [func_selector] + dup1 __FUNC_SIG(withdraw) eq withdraw_jump jumpi // [func_selector] + dup1 __FUNC_SIG(mint) eq mint_jump jumpi // [func_selector] + dup1 __FUNC_SIG(redeem) eq redeem_jump jumpi // [func_selector] + + dup1 __FUNC_SIG(totalAssets) eq total_assets_jump jumpi // [func_selector] + dup1 __FUNC_SIG(convertToShares) eq convert_to_shares_jump jumpi // [func_selector] + dup1 __FUNC_SIG(convertToAssets) eq convert_to_assets_jump jumpi // [func_selector] + dup1 __FUNC_SIG(previewDeposit) eq preview_deposit_jump jumpi // [func_selector] + dup1 __FUNC_SIG(previewMint) eq preview_mint_jump jumpi // [func_selector] + dup1 __FUNC_SIG(previewWithdraw) eq preview_withdraw_jump jumpi // [func_selector] + dup1 __FUNC_SIG(previewRedeem) eq preview_redeem_jump jumpi // [func_selector] + + dup1 __FUNC_SIG(maxDeposit) eq max_deposit_jump jumpi // [func_selector] + dup1 __FUNC_SIG(maxMint) eq max_mint_jump jumpi // [func_selector] + dup1 __FUNC_SIG(maxWithdraw) eq max_withdraw_jump jumpi // [func_selector] + dup1 __FUNC_SIG(maxRedeem) eq max_redeem_jump jumpi // [func_selector] + + ERC20_MAIN() // [func_selector] + + // Bubble up to the parent macro + no_match jump + + decimals_jump: + ERC4626_DECIMALS() + asset_jump: + ERC4626_ASSET() + + deposit_jump: + ERC4626_DEPOSIT() + withdraw_jump: + ERC4626_WITHDRAW() + mint_jump: + ERC4626_MINT() + redeem_jump: + ERC4626_REDEEM() + + total_assets_jump: + TOTAL_ASSETS() + convert_to_shares_jump: + CONVERT_TO_SHARES() + convert_to_assets_jump: + CONVERT_TO_ASSETS() + preview_deposit_jump: + PREVIEW_DEPOSIT() + preview_mint_jump: + PREVIEW_MINT() + preview_withdraw_jump: + PREVIEW_WITHDRAW() + preview_redeem_jump: + PREVIEW_REDEEM() + + max_deposit_jump: + MAX_DEPOSIT() + max_mint_jump: + MAX_MINT() + max_withdraw_jump: + MAX_WITHDRAW() + max_redeem_jump: + MAX_REDEEM() + + // Resume parent dispatching + no_match: // [func_selector] +} diff --git a/src/tokens/__TEMP__vvaewlzfkyljuiwoxdrktdnlhsuzsmbhERC721.huff b/src/tokens/__TEMP__vvaewlzfkyljuiwoxdrktdnlhsuzsmbhERC721.huff new file mode 100644 index 00000000..17f4c60b --- /dev/null +++ b/src/tokens/__TEMP__vvaewlzfkyljuiwoxdrktdnlhsuzsmbhERC721.huff @@ -0,0 +1,787 @@ + +#define function mint(address, uint256) payable returns () +#define function burn(uint256) nonpayable returns () + +#define function mint(address, uint256) payable returns () +#define function burn(uint256) nonpayable returns () + +#define function safeMint(address to, uint256 tokenId, bytes memory data) payable returns () +#define function safeMint(address to, uint256 tokenId) payable returns () + +#define macro CONSTRUCTOR() = takes (0) returns (0) { + ERC721_CONSTRUCTOR() +} + +#define macro MINT() = takes (0) returns (0) { + 0x24 calldataload // [tokenId] + 0x04 calldataload // [to, tokenId] + _MINT() + stop +} + +#define macro BURN() = takes (0) returns (0) { + 0x04 calldataload // [tokenId] + _BURN() + stop +} + +#define macro SAFE_MINT() = takes (0) returns (0) { + 0x24 calldataload // [tokenId] + 0x04 calldataload // [to, tokenId] + _MINT() + + // Safe Logic + // Make sure we can transfer to the recipient + 0x04 calldataload // [to] + dup1 extcodesize // [to.code.length, to] + iszero safe jumpi // [to] + + // onERC721Received Selector + 0x150b7a02 dup1 // [onERC721Received, onERC721Received, to] + 0xE0 shl // [onERC721Received_shifted, onERC721Received, to] + + // Store the left-shifted selector for call + 0x20 mstore // [onERC721Received, to] + + // Store the msg.sender as the first arg + caller 0x24 mstore // [onERC721Received, to] + + // Store address(0) as the second arg + 0x00 // [address(0), onERC721Received, to] + 0x44 mstore // [onERC721Received, to] + + // Id is the third arg + 0x24 calldataload // [tokenId, onERC721Received, to] + 0x64 mstore // [onERC721Received, to] + + // Blank bytes array as 4th arg (no data) + 0x80 0x84 mstore + 0x00 0xA4 mstore + + // Call address(to).onERC721Received(msg.sender, from, tokenId, "") + 0x20 // [retSize, onERC721Received, to] + 0x00 // [retOffset, retSize, onERC721Received, to] + 0xA4 // [argSize, retOffset, retSize, onERC721Received, to] + dup3 // [argOffset, argSize, retOffset, retSize, onERC721Received, to] + dup3 // [value, argOffset, argSize, retOffset, retSize, onERC721Received, to] + dup7 // [to, value, argOffset, argSize, retOffset, retSize, onERC721Received, to] + gas // [gas, to, value, argOffset, argSize, retOffset, retSize, onERC721Received, to] + call // [success, onERC721Received, to] + + // Revert if call isn't successful + cont jumpi // [onERC721Received, to] + 0x00 dup1 revert + cont: + + // Compare the return data to the onERC721Received selector + 0x00 mload 0xE0 shr // [response, onERC721Received, to] + eq safe jumpi // [to] + + // Revert if the return data is not accepted + UNSAFE_RECIPIENT(0x00) + + // Stop execution if safe + safe: + stop +} + +#define macro SAFE_MINT_WITH_DATA() = takes (0) returns (0) { + 0x44 calldataload // [data] + 0x24 calldataload // [tokenId, data] + 0x04 calldataload // [to, tokenId, data] + _MINT() + + // Make sure we can transfer to the recipient + 0x04 calldataload // [to] + dup1 extcodesize // [to.code.length, to] + iszero safe jumpi // [to] + + // onERC721Received Selector + 0x150b7a02 dup1 // [onERC721Received, onERC721Received, to] + 0xE0 shl // [onERC721Received_shifted, onERC721Received, to] + + // Store the left-shifted selector for call + 0x20 mstore // [onERC721Received, to] + + // Store the msg.sender as the first arg + caller 0x24 mstore // [onERC721Received, to] + + // Store address(0) as the second arg + 0x00 // [address(0), onERC721Received, to] + 0x44 mstore // [onERC721Received, to] + + // Id is the third arg + 0x24 calldataload // [tokenId, onERC721Received, to] + 0x64 mstore // [onERC721Received, to] + + // Store the pointer to the data length + 0x80 0x84 mstore // [onERC721Received, to] + + 0x64 calldataload // [len(data), onERC721Received, to] + 0x05 shl // [len(data) * 0x20, onERC721Received, to] + 0x20 add // [len(data) * 0x20 + 0x20, onERC721Received, to] + dup1 // [len(data) * 0x20 + 0x20, len(data) * 0x20 + 0x20, onERC721received, to] + 0x64 // [0x64, len(data) * 0x20 + 0x20, len(data) * 0x20 + 0x20, onERC721received, to] + 0xA4 // [0x84, 0x64, len(data) * 0x20 + 0x20, len(data) * 0x20 + 0x20, onERC721received, to] + calldatacopy // [len(bytes), onERC721received, to] + + // Call address(to).onERC721Received(msg.sender, from, tokenId, bytes) + 0x20 // [retSize, len(bytes), onERC721Received, to] + 0x00 // [retOffset, retSize, len(bytes), onERC721Received, to] + swap1 swap2 // [len(bytes), retOffset, retSize, onERC721Received, to] + 0x84 add // [argSize, retOffset, retSize, onERC721Received, to] + dup3 // [argOffset, argSize, retOffset, retSize, len(bytes), onERC721Received, to] + dup3 // [value, argOffset, argSize, retOffset, retSize, len(bytes), onERC721Received, to] + dup7 // [to, value, argOffset, argSize, retOffset, retSize, len(bytes), onERC721Received, to] + gas // [gas, to, value, argOffset, argSize, retOffset, retSize, len(bytes), onERC721Received, to] + call // [success, len(bytes), onERC721Received, to] + + // Revert if call isn't successful + selector_call_success jumpi // [len(bytes), onERC721Received, to] + 0x00 dup1 revert + selector_call_success: + + // Compare the return data to the onERC721Received selector + 0x00 mload 0xE0 shr // [response, onERC721Received, to] + eq safe jumpi // [to] + + // Revert if the return data is not accepted + UNSAFE_RECIPIENT(0x00) + + // Stop execution if safe + safe: + stop + +} + +// Function Dispatch +#define macro MAIN() = takes (0) returns (0) { + 0x00 calldataload 0xE0 shr // [sig] + + // Mint and Burning Functions + dup1 __FUNC_SIG(mint) eq mint_jump jumpi + dup1 __FUNC_SIG(burn) eq burn_jump jumpi + + dup1 __FUNC_SIG("safeMint(address,uint256)") eq safe_mint jumpi + dup1 __FUNC_SIG("safeMint(address,uint256,bytes)") eq safe_mint_with_data jumpi + + dup1 __FUNC_SIG(approve) eq approve jumpi + dup1 __FUNC_SIG(setApprovalForAll) eq setApprovalForAll jumpi + + dup1 __FUNC_SIG(transferFrom) eq transferFrom jumpi + dup1 __FUNC_SIG(safeTransferFrom) eq safeTransferFrom jumpi + + dup1 __FUNC_SIG(name) eq name jumpi + dup1 __FUNC_SIG(symbol) eq symbol jumpi + dup1 __FUNC_SIG(tokenURI) eq tokenURI jumpi + dup1 __FUNC_SIG(supportsInterface) eq supportsInterface jumpi + + dup1 __FUNC_SIG(getApproved) eq getApproved jumpi + dup1 __FUNC_SIG(isApprovedForAll) eq isApprovedForAll jumpi + + dup1 __FUNC_SIG(balanceOf) eq balanceOf jumpi + dup1 __FUNC_SIG(ownerOf) eq ownerOf jumpi + + dup1 __FUNC_SIG("safeTransferFrom(address,address,uint256,bytes)") eq safeTransferFromData jumpi + + // Revert on failed dispatch + 0x00 dup1 revert + + safe_mint: + SAFE_MINT() + safe_mint_with_data: + SAFE_MINT_WITH_DATA() + + mint_jump: + MINT() + burn_jump: + BURN() + + approve: + APPROVE() + setApprovalForAll: + SET_APPROVAL_FOR_ALL() + + transferFrom: + TRANSFER_FROM() + safeTransferFrom: + SAFE_TRANSFER_FROM() + safeTransferFromData: + SAFE_TRANSFER_FROM_WITH_DATA() + + name: + NAME() + symbol: + SYMBOL() + tokenURI: + TOKEN_URI() + supportsInterface: + SUPPORTS_INTERFACE() + + getApproved: + GET_APPROVED() + isApprovedForAll: + IS_APPROVED_FOR_ALL() + + balanceOf: + BALANCE_OF() + ownerOf: + OWNER_OF() +} + + +/// @title ERC721 +/// @notice SPDX-License-Identifier: MIT +/// @author asnared +/// @author kadenzipfel +/// @notice Modern and heavily gas golfed ERC-721 implementation +/// @notice Adapted from Solmate https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC721.sol + +// Imports +#include "../utils/CommonErrors.huff" +#include "../auth/NonPayable.huff" +#include "../data-structures/Hashmap.huff" + +// Interface +#define function name() nonpayable returns (string) +#define function symbol() nonpayable returns (string) +#define function tokenURI(uint256) nonpayable returns (string) + +#define function mint(address, uint256) payable returns () +#define function burn(uint256) nonpayable returns () + +#define function transfer(address,uint256) nonpayable returns () +#define function transferFrom(address,address,uint256) nonpayable returns () +#define function safeTransferFrom(address,address,uint256) nonpayable returns () +#define function safeTransferFrom(address,address,uint256,bytes) nonpayable returns () + +#define function approve(address,uint256) nonpayable returns () +#define function setApprovalForAll(address,bool) nonpayable returns () + +#define function getApproved(uint256) view returns (address) +#define function isApprovedForAll(address,address) view returns (bool) +#define function ownerOf(uint256) view returns (address) +#define function balanceOf(address) view returns (uint256) +#define function supportsInterface(bytes4) view returns (bool) + +// Events +#define event Transfer(address,address,uint256) +#define event Approval(address,address,uint256) +#define event ApprovalForAll(address,address,bool) + +// Storage Slots +#define constant OWNER_LOCATION = FREE_STORAGE_POINTER() +#define constant BALANCE_LOCATION = FREE_STORAGE_POINTER() +#define constant SINGLE_APPROVAL_LOCATION = FREE_STORAGE_POINTER() + +// Immutables offsets +#define constant NAME_OFFSET = 0x0000000000000000000000000000000000000000000000000000000000000080 +#define constant NAME_LENGTH_OFFSET = 0x00000000000000000000000000000000000000000000000000000000000000a0 +#define constant SYMBOL_OFFSET = 0x0000000000000000000000000000000000000000000000000000000000000020 +#define constant SYMBOL_LENGTH_OFFSET = 0x0000000000000000000000000000000000000000000000000000000000000040 + +/// >>>>>>>>>>>>>>>>>>>>> CONSTRUCTOR <<<<<<<<<<<<<<<<<<<<<< /// + +/// @notice Constructor +#define macro ERC721_CONSTRUCTOR() = takes (0) returns (0) { + // Constructor arguments: + // ?, name_size, name, ?, symbol_size, symbol + + // This constructor will return the runtime bytecode with all the + // constructor arguments concatenated at the end. + + // Copy the runtime bytecode with constructor argument concatenated. + 0xb // [offset] - constructor code size + dup1 // [offset, offset] + codesize // [total_size, offset, offset] + sub // [runtime_size, offset] + dup1 // [runtime_size, runtime_size, offset] + swap2 // [offset, runtime_size, runtime_size] + returndatasize // [return_offset, offset, runtime_size, runtime_size] + codecopy // [runtime_size] + + // Return the runtime bytecode. + returndatasize // [return_offset, runtime_size] + return // [] +} + +/// >>>>>>>>>>>>>>>>>>>>> VIEW FUNCTIONS <<<<<<<<<<<<<<<<<<<<<< /// + +/// @notice Name +/// @notice Returns the token name string +#define macro NAME() = takes (0) returns (0) { + NON_PAYABLE() // [] + _GET_IMMUTABLE(NAME_OFFSET, 0x00) // [name_value] + _GET_IMMUTABLE(NAME_LENGTH_OFFSET, 0x00) // [name_length, name_value] + 0x20 0x00 mstore // [name_length, name_value] + 0x20 mstore // [name_value] + 0x40 mstore // [] + 0x60 0x00 return // [] +} + +/// @notice Symbol +/// @notice Returns the symbol of the token +#define macro SYMBOL() = takes (0) returns (0) { + NON_PAYABLE() // [] + _GET_IMMUTABLE(SYMBOL_OFFSET, 0x00) // [symbol_value] + _GET_IMMUTABLE(SYMBOL_LENGTH_OFFSET, 0x00) // [symbol_length, symbol_value] + 0x20 0x00 mstore // [symbol_length, symbol_value] + 0x20 mstore // [symbol_value] + 0x40 mstore // [] + 0x60 0x00 return // [] +} + +/// @notice Balance Of +/// @notice Returns the balance of the given address +#define macro BALANCE_OF() = takes (0) returns (0) { + NON_PAYABLE() // [] + 0x04 calldataload // [account] + [BALANCE_LOCATION] LOAD_ELEMENT_FROM_KEYS(0x00) // [balance] + 0x00 mstore // [] + 0x20 0x00 return // [] +} + +/// @notice Owner Of +/// @notice Returns the owner of the given token id +#define macro OWNER_OF() = takes (0) returns (0) { + 0x04 calldataload // [tokenId] + [OWNER_LOCATION] LOAD_ELEMENT_FROM_KEYS(0x00) // [owner] + 0x00 mstore // [] + 0x20 0x00 return // [] +} + +/// @notice Is Approved For All +/// @notice Returns whether the given operator is approved for all tokens of the given owner +#define macro IS_APPROVED_FOR_ALL() = takes (0) returns (0) { + 0x24 calldataload // [to] + 0x04 calldataload // [from, to] + LOAD_ELEMENT_FROM_KEYS(0x00) // [value] + 0x00 mstore // [] + 0x20 0x00 return // [] +} + +/// @notice Get Approved +/// @notice Returns the approved address for the given token id +#define macro GET_APPROVED() = takes (0) returns (0) { + 0x04 calldataload // [tokenId] + [SINGLE_APPROVAL_LOCATION] // [approval_slot, tokenId] + LOAD_ELEMENT_FROM_KEYS(0x00) // [spender] + 0x00 mstore // [] + 0x20 0x00 return // [] +} + +/// @notice Token URI +#define macro TOKEN_URI() = takes (0) returns (0) { + 0x20 0x00 mstore + 0x00 0x20 mstore + 0x40 0x00 return +} + +/// @notice Checks if the given interface is supported +#define macro SUPPORTS_INTERFACE() = takes (0) returns (0) { + // grab interfaceId + 0x04 calldataload // [interfaceId] + 0xe0 shr // [right_aligned_interfaceId] + + // Check if erc165 interfaceId + dup1 // [interfaceId, interfaceId] + 0x01ffc9a7 eq // [is_erc165, interfaceId] + is_interface jumpi + + // Check if erc721 interfaceId + dup1 // [interfaceId, interfaceId] + 0x80ac58cd eq // [is_erc721, interfaceId] + is_interface jumpi + + // Check if erc721Metadata interfaceId + 0x5b5e139f eq // [is_erc721Metadata] + is_interface jumpi + + // Return false (0x00) + 0x00 mstore // [] + 0x20 0x00 return // [] + + // Return true (0x01) + is_interface: + pop // [] + 0x01 0x00 mstore // [] + 0x20 0x00 return // [] +} + +/// >>>>>>>>>>>>>>>>>>>>> INTERNAL FUNCTIONS <<<<<<<<<<<<<<<<<<<<<< /// + +/// @notice Mint +/// @notice Mints a new token +/// @dev The Mint function is payable +#define macro _MINT() = takes (2) returns (0) { + // Input stack: // [to, tokenId] + // Output stack: // [] + + // Check that the recipient is valid + dup1 iszero invalid_recipient jumpi // [to, tokenId] + + // Create the minting params + 0x00 dup3 // [tokenId, from (0x00), to, tokenId] + + // Check token ownership + [OWNER_LOCATION] LOAD_ELEMENT_FROM_KEYS(0x00) // [owner, from (0x00), to, tokenId] + iszero iszero unauthorized jumpi + + // Give tokens to the recipient. + TRANSFER_GIVE_TO() // [from (0x00), to, tokenId] + + // Emit the transfer event. + __EVENT_HASH(Transfer) // [sig, from (0x00), to, tokenId] + 0x00 0x00 log4 // [] + + // Continue Executing + cont jump + + invalid_recipient: + INVALID_RECIPIENT(0x00) + + unauthorized: + ALREADY_MINTED(0x00) + + cont: +} + +/// @notice Burn +/// @notice Burns the token with the given id +#define macro _BURN() = takes (1) returns (0) { + // Input stack: // [tokenId] + NON_PAYABLE() // [tokenId] + + dup1 // [tokenId, tokenId] + [OWNER_LOCATION] LOAD_ELEMENT_FROM_KEYS(0x00) // [owner, tokenId] + + // Check that the recipient is valid + dup1 iszero // [owner == 0, owner, tokenId] + not_minted jumpi // [owner, tokenId] + + // Create the burning params + 0x00 swap1 // [owner, to (0x00), tokenId] + + // Reduce the balance of owner by 1 + 0x01 dup2 // [owner, 1, owner, to, tokenId] + [BALANCE_LOCATION] LOAD_ELEMENT_FROM_KEYS(0x00) // [balance, 1, owner, to, tokenId] + sub dup2 // [owner, balance-1, owner, to, tokenId] + [BALANCE_LOCATION] + STORE_ELEMENT_FROM_KEYS(0x00) // [owner, to, tokenId] + + // Set the owner of the token to 0x00 + 0x00 dup4 [OWNER_LOCATION] // [slot, owner, 0x00, owner, to, tokenId] + STORE_ELEMENT_FROM_KEYS(0x00) // [owner, to, tokenId] + + // Set the approval of the token to 0x00 for the owner + 0x00 dup4 [SINGLE_APPROVAL_LOCATION] // [slot, owner, 0x00, owner, to, tokenId] + STORE_ELEMENT_FROM_KEYS(0x00) // [owner, to, tokenId] + + // Emit the transfer event. + __EVENT_HASH(Transfer) // [sig, owner, to (0x00), tokenId] + 0x00 0x00 // [0, 0, sig, owner, to (0x00), tokenId] + log4 // [] + + // Continue Executing + cont jump + + not_minted: + NOT_MINTED(0x00) + + cont: +} + +/// @notice Retrives an "immutable" from the runtime bytecode. +#define macro _GET_IMMUTABLE(offset_end, free_memory) = takes (0) returns (1) { + 0x20 // [size] + codesize sub // [offset_code, size] + // [offset_memory, offset_code, size] + codecopy // [] + mload // [value] +} + +/// >>>>>>>>>>>>>>>>>>>>> EXTERNAL FUNCTIONS <<<<<<<<<<<<<<<<<<<<<< /// + +/// @notice Approve +/// @notice Approves a spender for a specific token +#define macro APPROVE() = takes (0) returns (0) { + // Load the token owner + 0x24 calldataload dup1 // [tokenId, tokenId] + [OWNER_LOCATION] + LOAD_ELEMENT_FROM_KEYS(0x00) // [owner, tokenId] + dup1 caller eq // [is_sender_owner, owner, tokenId] + + // Check if approved for all + caller dup3 // [owner, msg.sender, is_sender_owner, owner, tokenId] + LOAD_ELEMENT_FROM_KEYS(0x00) // [is_approved_for_all, is_sender_owner, owner, tokenId]] + or cont jumpi // [owner, tokenId] + not_authorized jump + cont: + + // Store approval + 0x04 calldataload dup1 dup4 // [tokenId, spender, spender, owner, tokenId] + [SINGLE_APPROVAL_LOCATION] + STORE_ELEMENT_FROM_KEYS(0x00) // [spender, owner, tokenId] + swap1 // [owner, spender, tokenId] + + // Emit the approval event + __EVENT_HASH(Approval) // [sig, owner, spender, tokenId] + 0x00 0x00 log4 // [] + + stop + + not_authorized: + UNAUTHORIZED(0x00) +} + +/// @notice Set Approval For All +/// @notice Sets an operator as approved for all tokens of the caller +#define macro SET_APPROVAL_FOR_ALL() = takes (0) returns (0) { + // Store the operator as approved for all + 0x24 calldataload // [approved] + 0x04 calldataload // [operator, approved] + caller // [msg.sender, operator, approved] + STORE_ELEMENT_FROM_KEYS(0x00) // [] + + // Emit the ApprovalForAll event + 0x24 calldataload // [approved] + 0x04 calldataload // [operator, approved] + caller // [msg.sender, operator, approved] + __EVENT_HASH(ApprovalForAll) // [sig, owner, operator] + 0x00 0x00 // [0, 32, sig, owner, operator] + log4 // [] + + // Stop execution + stop +} + +/// @notice Transfer From +/// @notice Transfers a token from one address to another +#define macro TRANSFER_FROM() = takes (0) returns (0) { + // Setup the stack for the transfer function. + 0x44 calldataload // [tokenId] + 0x24 calldataload // [to, tokenId] + 0x04 calldataload // [from, to, tokenId] + + // Accounting Logic + TRANSFER_TAKE_FROM() // [from, to, tokenId] + TRANSFER_GIVE_TO() // [from, to, tokenId] + + // Emit the transfer event + __EVENT_HASH(Transfer) // [sig,from, to, tokenId] + 0x20 0x00 log4 // [] + + // Stop execution + stop +} + +/// @notice Safe Transfer From +#define macro SAFE_TRANSFER_FROM() = takes (0) returns (0) { + // Setup the stack for the transfer function. + 0x44 calldataload // [tokenId] + 0x24 calldataload // [to, tokenId] + 0x04 calldataload // [from, to, tokenId] + + TRANSFER_TAKE_FROM() // [from, to, tokenId] + TRANSFER_GIVE_TO() // [from, to, tokenId] + + // Emit the transfer event + __EVENT_HASH(Transfer) // [sig, from, to, tokenId] + 0x00 0x00 log4 // [] + + // Make sure we can transfer to the recipient + 0x24 calldataload // [to] + dup1 extcodesize // [to.code.length, to] + iszero safe jumpi // [to] + + // onERC721Received Selector + 0x150b7a02 dup1 // [onERC721Received, onERC721Received, to] + 0xE0 shl // [onERC721Received_shifted, onERC721Received, to] + + // Store the left-shifted selector for call + 0x20 mstore // [onERC721Received, to] + + // Store the msg.sender as the first arg + caller 0x24 mstore // [onERC721Received, to] + + // Store from as the second arg + 0x04 calldataload // [from, onERC721Received, to] + 0x44 mstore // [onERC721Received, to] + + // Id is the third arg + 0x44 calldataload // [tokenId, onERC721Received, to] + 0x64 mstore // [onERC721Received, to] + + // Blank bytes array as 4th arg (no data) + 0x80 0x84 mstore + 0x00 0xA4 mstore + + // Call address(to).onERC721Received(msg.sender, from, tokenId, "") + 0x20 // [retSize, onERC721Received, to] + 0x00 // [retOffset, retSize, onERC721Received, to] + 0xA4 // [argSize, retOffset, retSize, onERC721Received, to] + dup3 // [argOffset, argSize, retOffset, retSize, onERC721Received, to] + dup3 // [value, argOffset, argSize, retOffset, retSize, onERC721Received, to] + dup7 // [to, value, argOffset, argSize, retOffset, retSize, onERC721Received, to] + gas // [gas, to, value, argOffset, argSize, retOffset, retSize, onERC721Received, to] + call // [success, onERC721Received, to] + + // Revert if call isn't successful + cont jumpi // [onERC721Received, to] + 0x00 dup1 revert + cont: + + // Compare the return data to the onERC721Received selector + 0x00 mload 0xE0 shr // [response, onERC721Received, to] + eq safe jumpi // [to] + + // Revert if the return data is not accepted + UNSAFE_RECIPIENT(0x00) + + // Stop execution if safe + safe: + stop +} + +#define macro SAFE_TRANSFER_FROM_WITH_DATA() = takes (0) returns (0) { + // Setup the stack for the transfer function. + 0x44 calldataload // [tokenId] + 0x24 calldataload // [to, tokenId] + 0x04 calldataload // [from, to, tokenId] + + TRANSFER_TAKE_FROM() // [from, to, tokenId] + TRANSFER_GIVE_TO() // [from, to, tokenId] + + // Emit the transfer event. + __EVENT_HASH(Transfer) // [sig, from, to, tokenId] + 0x00 0x00 log4 // [] + + // Make sure we can transfer to the recipient + 0x24 calldataload // [to] + dup1 extcodesize // [to.code.length, to] + iszero safe jumpi // [to] + + // onERC721Received Selector + 0x150b7a02 dup1 // [onERC721Received, onERC721Received, to] + 0xE0 shl // [onERC721Received_shifted, onERC721Received, to] + + // Store the left-shifted selector for call + 0x20 mstore // [onERC721Received, to] + + // Store the msg.sender as the first arg + caller 0x24 mstore // [onERC721Received, to] + + // Store from as the second arg + 0x04 calldataload // [from, onERC721Received, to] + 0x44 mstore // [onERC721Received, to] + + // Id is the third arg + 0x44 calldataload // [tokenId, onERC721Received, to] + 0x64 mstore // [onERC721Received, to] + + 0x84 calldataload // [len(data), onERC721Received, to] + 0x05 shl // [len(data) * 0x20, onERC721Received, to] + 0x40 add // [len(data) * 0x20 + 0x40, onERC721Received, to] + dup1 // [len(data) * 0x20 + 0x40, len(data) * 0x20 + 0x40, onERC721received, to] + 0x64 // [0x64, len(data) * 0x20 + 0x40, len(data) * 0x20 + 0x40, onERC721received, to] + 0x84 // [0x20, 0x64, len(data) * 0x20 + 0x40, len(data) * 0x20 + 0x40, onERC721received, to] + calldatacopy // [len(bytes), onERC721received, to] + + // Call address(to).onERC721Received(msg.sender, from, tokenId, bytes) + 0x20 // [retSize, len(bytes), onERC721Received, to] + 0x00 // [retOffset, retSize, len(bytes), onERC721Received, to] + swap1 swap2 // [len(bytes), retOffset, retSize, onERC721Received, to] + 0x64 add // [argSize, retOffset, retSize, onERC721Received, to] + dup3 // [argOffset, argSize, retOffset, retSize, len(bytes), onERC721Received, to] + dup3 // [value, argOffset, argSize, retOffset, retSize, len(bytes), onERC721Received, to] + dup7 // [to, value, argOffset, argSize, retOffset, retSize, len(bytes), onERC721Received, to] + gas // [gas, to, value, argOffset, argSize, retOffset, retSize, len(bytes), onERC721Received, to] + call // [success, len(bytes), onERC721Received, to] + + // Revert if call isn't successful + cont jumpi // [len(bytes), onERC721Received, to] + 0x00 dup1 revert + cont: + + // Compare the return data to the onERC721Received selector + 0x00 mload 0xE0 shr // [response, onERC721Received, to] + eq safe jumpi // [to] + + // Revert if the return data is not accepted + UNSAFE_RECIPIENT(0x00) + + // Stop execution if safe + safe: + stop +} + +/// >>>>>>>>>>>>>>>>>>>>> INTERNAL HELPERS <<<<<<<<<<<<<<<<<<<<<< /// + +/// @notice Internal Macro to update Transfer from accounting +#define macro TRANSFER_TAKE_FROM() = takes (3) returns (3) { + // Input stack: [from, to, tokenId] + + // If from !== ownerOf[tokenId] revert with "WRONG_FROM" + dup1 dup4 // [tokenId, from, from, to, tokenId] + [OWNER_LOCATION] LOAD_ELEMENT_FROM_KEYS(0x00) // [owner, from, from, to, tokenId] + eq cont jumpi // [from, to, tokenId] + WRONG_FROM(0x00) + cont: + + // If to === address(0) revert with "INVALID_RECIPIENT" + dup2 iszero iszero continue jumpi // [from, to, tokenId] + INVALID_RECIPIENT(0x00) + continue: + + // Check if msg.sender == from + dup1 caller eq // [msg.sender == from, from, to, tokenId] + is_authorized jumpi // [from, to, tokenId] + + // Check if approved for all + caller dup2 // [from, msg.sender, from, to, tokenId] + LOAD_ELEMENT_FROM_KEYS(0x00) // [is_approved_for_all, from, to, tokenId] + is_authorized jumpi // [from, to, tokenId] + + // Check if approved for tokenId + dup3 // [tokenId, from, to, tokenId] + [SINGLE_APPROVAL_LOCATION] // [SINGLE_APPROVAL_LOCATION, tokenId, from, to, tokenId] + LOAD_ELEMENT_FROM_KEYS(0x00) // [address_approved_for_tokenId, from, to, tokenId] + caller eq is_authorized jumpi // [from, to, tokenId] + + // If msg.sender != from && !isApprovedForAll[from][msg.sender] && msg.sender != getApproved[id], + UNAUTHORIZED(0x00) + + is_authorized: + + // Update balance of from + 0x01 dup2 // [from, 1, from, to, tokenId] + [BALANCE_LOCATION] LOAD_ELEMENT_FROM_KEYS(0x00) // [balance, 1, from, to, tokenId] + sub dup2 // [from, balance-1, from, to, tokenId] + [BALANCE_LOCATION] + STORE_ELEMENT_FROM_KEYS(0x00) // [from, to, tokenId] +} + +/// @notice Internal Macro to update Transfer to accounting +#define macro TRANSFER_GIVE_TO() = takes (3) returns (3) { + // retrieve balance + // input stack: // [from, to, tokenId] + dup2 // [to, from, to, tokenId] + [BALANCE_LOCATION] // [balance_slot, to, from, to, tokenId] + LOAD_ELEMENT_FROM_KEYS(0x00) // [balance, from, to, tokenId] + 0x01 add // [balance+1, from, to, tokenId] + + // update balance + dup3 // [to, balance+1, from, to, tokenId] + [BALANCE_LOCATION] // [balance_slot, to, balance+1, from, to, tokenId] + STORE_ELEMENT_FROM_KEYS(0x00) // [from, to, tokenId] + + // update ownerOf + dup2 dup4 // [tokenId, to, from, to, tokenId] + [OWNER_LOCATION] // [owner_slot, tokenId, to, from, to, tokenId] + STORE_ELEMENT_FROM_KEYS(0x00) // [from, to, tokenId] + + // update approval + 0x00 dup4 // [tokenId, address(0), from, to, tokenId] + [SINGLE_APPROVAL_LOCATION] // [approval_slot, tokenId, address(0), from, to, tokenId] + STORE_ELEMENT_FROM_KEYS(0x00) // [from, to, tokenId] +} diff --git a/src/tokens/__TEMP__zxgqnylgrbytfwvkvdnlnpcvxmcecsliERC4626.huff b/src/tokens/__TEMP__zxgqnylgrbytfwvkvdnlnpcvxmcecsliERC4626.huff new file mode 100644 index 00000000..5e3a3cbb --- /dev/null +++ b/src/tokens/__TEMP__zxgqnylgrbytfwvkvdnlnpcvxmcecsliERC4626.huff @@ -0,0 +1,859 @@ + +#define function beforeWithdrawHookCalledCounter() nonpayable returns (uint256) +#define function afterDepositHookCalledCounter() nonpayable returns (uint256) + +#define constant BEFORE_HOOK_COUNTER = FREE_STORAGE_POINTER() +#define constant AFTER_HOOK_COUNTER = FREE_STORAGE_POINTER() + +#define macro CONSTRUCTOR() = takes (0) returns (0) { + ERC4626_CONSTRUCTOR() // [] +} + +#define macro BEFORE_WITHDRAW() = takes (2) returns (0) { + // Input Stack: [assets, shares] + // Output Stack: [] + pop pop // [] + [BEFORE_HOOK_COUNTER] sload // [counter] + 0x01 add // [counter + 1] + [BEFORE_HOOK_COUNTER] sstore // [] +} + +#define macro AFTER_DEPOSIT() = takes (2) returns (0) { + // Input Stack: [assets, shares] + // Output Stack: [] + pop pop // [] + [AFTER_HOOK_COUNTER] sload // [counter] + 0x01 add // [counter + 1] + [AFTER_HOOK_COUNTER] sstore // [] +} + +#define macro READ_BEFORE_HOOK_COUNTER() = takes (0) returns (0) { + [BEFORE_HOOK_COUNTER] sload // [counter] + 0x00 mstore // [] + 0x20 0x00 return // [] +} + +#define macro READ_AFTER_HOOK_COUNTER() = takes (0) returns (0) { + [AFTER_HOOK_COUNTER] sload // [counter] + 0x00 mstore // [] + 0x20 0x00 return // [] +} + +#define macro TOTAL_ASSETS_INNER() = takes (0) returns (1) { + // Input Stack: [] + // Output Stack: [total_assets] + + // Store the asset.balanceOf(address(this)) args in memory + __FUNC_SIG(balanceOf) + 0xE0 shl + 0x20 mstore + address 0x24 mstore + + // Get the asset variable + _GET_IMMUTABLE(ASSET_OFFSET, 0x80) // [asset] + + // Construct the call + 0x20 // [retSize, asset] + 0x00 // [retOffset, retSize, asset] + 0x24 // [argSize, retOffset, retSize, asset] + 0x20 // [argOffset, argSize, retOffset, retSize, asset] + 0x00 // [value, argOffset, argSize, retOffset, retSize, asset] + dup6 // [to, value, argOffset, argSize, retOffset, retSize, asset] + gas // [gas, to, value, argOffset, argSize, retOffset, retSize, asset] + call // [success, asset] + + // Verify the call succeeded + iszero iszero success jumpi // [asset] + 0x00 dup1 revert // [] + success: + + // Since the returndata is copied to [0x00:0x20], we can just mload + pop 0x00 mload // [total_assets] +} + + +#define macro MAIN() = takes (0) returns (0) { + pc calldataload 0xE0 shr // [sig] + + dup1 __FUNC_SIG(beforeWithdrawHookCalledCounter) eq before_jump jumpi // [sig] + dup1 __FUNC_SIG(afterDepositHookCalledCounter) eq after_jump jumpi // [sig] + + ERC4626_MAIN() // [sig] + + 0x00 dup1 revert + + before_jump: + READ_BEFORE_HOOK_COUNTER() + after_jump: + READ_AFTER_HOOK_COUNTER() +} + + +/// @title ERC4626 +/// @notice SPDX-License-Identifier: MIT +/// @author asnared +/// @notice Minimal ERC4626 tokenized Vault implementation. +/// @notice Adapted from Solmate (https://github.com/transmissions11/solmate/blob/main/src/mixins/ERC4626.sol) + +// ERC4626 is ERC20 +#include "./ERC20.huff" +#include "../utils/CommonErrors.huff" +#include "../math/FixedPointMath.huff" + +// Events +#define event Deposit(address indexed caller, address indexed owner, uint256 assets, uint256 shares) +#define event Withdraw(address indexed caller, address indexed receiver, address indexed owner, uint256 assets, uint256 shares) + +// Interface +#define function asset() view returns (address) + +#define function deposit(uint256 assets, address receiver) payable returns (uint256 shares) +#define function withdraw(uint256 assets, address receiver, address owner) payable returns (uint256 shares) +#define function mint(uint256 shares, address receiver) payable returns (uint256 assets) +#define function redeem(uint256 shares, address receiver, address owner) payable returns (uint256 assets) + +#define function totalAssets() view returns (uint256) +#define function convertToShares(uint256 assets) view returns (uint256) +#define function convertToAssets(uint256 shares) view returns (uint256) +#define function previewDeposit(uint256 assets) view returns (uint256) +#define function previewMint(uint256 shares) view returns (uint256) +#define function previewWithdraw(uint256 assets) view returns (uint256) +#define function previewRedeem(uint256 shares) view returns (uint256) + +#define function maxDeposit(address) view returns (uint256) +#define function maxMint(address) view returns (uint256) +#define function maxWithdraw(address owner) view returns (uint256) +#define function maxRedeem(address owner) view returns (uint256) + +// Immutables offsets +#define constant ASSET_OFFSET = 0x0000000000000000000000000000000000000000000000000000000000000100 + +#define constant TYPE_UINT_256_MAX = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + +/// @notice Constructor +#define macro ERC4626_CONSTRUCTOR() = takes (0) returns (0) { + // Copy the asset address into memory and then the stack from the bytecode + 0x20 // [size] - byte size to copy + 0x20 [ASSET_OFFSET] sub // [asset_offset_now, size] + codesize sub // [offset, size] - offset in the code to copy from + 0x00 // [mem, offset, size] - offset in memory to copy to + codecopy // [] - stores asset at 0x00 + + // Store the decimals function selector in memory to call + __FUNC_SIG(decimals) // [sig_right_padded] + 0xE0 shl // [sig_left_padded] + 0x20 mstore // [] + + // Call the asset to get its decimals + 0x20 // [retSize] + 0x00 // [retOffset, retSize] + 0x04 // [argSize, retOffset, retSize] + 0x20 // [argOffset, argSize, retOffset, retSize] + 0x00 mload // [to, argOffset, argSize, retOffset, retSize] + gas // [gas, to, argOffset, argSize, retOffset, retSize] + staticcall // [success] + + // If the call failed, revert + cont jumpi // [] + 0x00 dup1 revert // [] + cont: + + // Load the decimals + 0x00 mload // [decimals] + + // Configure the initial domain separator + chainid [INITIAL_CHAIN_ID] sstore // [decimals] + COMPUTE_DOMAIN_SEPARATOR() // [DOMAIN_SEPARATOR, decimals] + [INITIAL_DOMAIN_SEPARATOR] sstore // [decimals] + + // Copy the runtime bytecode with constructor argument concatenated. + __codesize(CONSTRUCTOR) // [offset, decimals] + dup1 // [offset, offset, decimals] + codesize // [total_size, offset, offset, decimals] + sub // [runtime_size, offset, decimals] + dup1 // [runtime_size, runtime_size, offset, decimals] + swap2 // [offset, runtime_size, runtime_size, decimals] + returndatasize // [return_offset, offset, runtime_size, runtime_size, decimals] + codecopy // [runtime_size, decimals] + + // Add the decimals at the of the bytecode. + swap1 // [decimals, runtime_size] + dup2 // [runtime_size, decimals, runtime_size] + returndatasize add mstore // [runtime_size] + + // Return the runtime bytecode. + 0x20 add // [new_runtime_size] + returndatasize // [return_offset, new_runtime_size] + return // [] +} + +/// @notice Returns the ERC4626 decimals +#define macro ERC4626_DECIMALS() = takes (0) returns (0) { + _GET_IMMUTABLE(DECIMALS_OFFSET, 0x00) // [decimals] + 0x00 mstore // [] + 0x20 0x00 return // [] +} + +/// @notice Returns the ERC4626 asset +#define macro ERC4626_ASSET() = takes (0) returns (0) { + _GET_IMMUTABLE(ASSET_OFFSET, 0x00) // [asset] + 0x00 mstore // [] + 0x20 0x00 return // [] +} + +// ------------------------------------------------------ +// DEPOSIT/WITHDRAWAL LOGIC +// ------------------------------------------------------ + +/// @notice Mint +/// @notice Mints a {receiver} x amount of {assets} proportional to the input {shares} +/// @param {shares} [uint256] The amount of shares to mint +#define macro ERC4626_MINT() = takes (0) returns (0) { + 0x24 calldataload // [receiver] + 0x04 calldataload // [shares, receiver] + MINT_INNER() // [assets] + 0x00 mstore // [] + 0x20 0x00 return // [] +} + +/// @notice Mint Internal Helper +#define macro MINT_INNER() = takes (2) returns (1) { + // Input stack: [shares, receiver] + // Output stack: [assets] + + // Preview the mint given the number of shares + dup1 // [shares, shares, receiver] + PREVIEW_MINT_INNER() // [assets, shares, receiver] + + // Transfer the assets from the caller to the vault + + // Store the transferFrom selector in memory + __FUNC_SIG(transferFrom) // [selector, assets, shares, receiver] + 0xE0 shl // [selector, assets, shares, receiver] + 0x00 mstore // [assets, shares, receiver] + + // Store the caller in memory as the first arg + caller 0x04 mstore // [assets, shares, receiver] + + // Store this address as the second call argument in memory + address 0x24 mstore // [assets, shares, receiver] + + // Store assets as the third call argument in memory + dup1 0x44 mstore // [assets, shares, receiver] + + // Load the asset as the call destination + _GET_IMMUTABLE(ASSET_OFFSET, 0x80) // [asset, assets, shares, receiver] + + // Construct the call + 0x00 // [retSize, asset, assets, shares, receiver] + 0x00 // [retOffset, retSize, asset, assets, shares, receiver] + 0x64 // [argSize, retOffset, retSize, asset, assets, shares, receiver] + 0x00 // [argOffset, argSize, retOffset, retSize, asset, assets, shares, receiver] + 0x00 // [value, argOffset, argSize, retOffset, retSize, asset, assets, shares, receiver] + dup6 // [to, value, argOffset, argSize, retOffset, retSize, asset, assets, shares, receiver] + gas // [gas, to, value, argOffset, argSize, retOffset, retSize, asset, assets, shares, receiver] + call // [success, asset, assets, shares, receiver] + + // Verify the call succeeded + success jumpi // [asset, assets, shares, receiver] + 0x00 dup1 revert // [] + success: + + // Mint vault shares to the receiver + pop // [assets, shares, receiver] + dup3 dup3 // [shares, receiver, assets, shares, receiver] + _MINT() // [assets, shares, receiver] + + // Emit the deposit event + dup1 0x00 mstore // [assets, shares, receiver] + dup2 0x20 mstore // [assets, shares, receiver] + dup3 caller // [msg.sender, receiver, assets, shares, receiver] + __EVENT_HASH(Deposit) // [event_hash, msg.sender, receiver, assets, shares, receiver] + 0x40 0x00 log3 // [assets, shares, receiver] + + // Call the after deposit hook + swap1 dup2 // [assets, shares, assets, receiver] + AFTER_DEPOSIT() // [assets, receiver] + + // Return just the assets + swap1 pop // [assets] +} + +/// @notice Redeem +/// @notice Redeems a {receiver} x amount of {assets} proportional to the input {shares} +/// @param {shares} [uint256] The amount of shares to redeem +/// @param {receiver} [address] The address to receive the assets +/// @param {owner} [address] The address that owns the shares +#define macro ERC4626_REDEEM() = takes (0) returns (0) { + 0x44 calldataload // [owner] + 0x24 calldataload // [receiver, owner] + 0x04 calldataload // [shares, receiver, owner] + REDEEM_INNER() // [assets] + 0x00 mstore // [] + 0x20 0x00 return // [] +} + +/// @notice Redeem Internal Helper +#define macro REDEEM_INNER() = takes (3) returns (1) { + // Input stack: [shares, receiver, owner] + // Output stack: [assets] + + // Jump ahead if msg.sender == owner + dup3 caller eq ahead jumpi // [shares, receiver, owner] + + // Check if the caller is approved to redeem the shares + + // Get the allowance[owner][msg.sender] + caller dup4 // [owner, msg.sender, shares, receiver, owner] + [APPROVAL_SLOT] // [slot, owner, msg.sender, shares, receiver, owner] + LOAD_ELEMENT_FROM_KEYS_2D(0x00) // [allowance, shares, receiver, owner] + + // If the allowed is no infinite approval, set to the allowance less shares + dup1 [TYPE_UINT_256_MAX] // [type(uint256).max, allowance, allowance, shares, receiver, owner] + eq infinite jumpi // [allowance, shares, receiver, owner] + + // Set the new allowance + dup2 dup2 sub // [new_allowance, allowance, shares, receiver, owner] + caller dup6 [APPROVAL_SLOT] // [slot, owner, msg.sender, new_allowance, allowance, shares, receiver, owner] + STORE_ELEMENT_FROM_KEYS_2D(0x00) // [allowance, shares, receiver, owner] + + // Jump dests for initial checks + infinite: + pop // [shares, receiver, owner] + ahead: + + // Validate that the assets are non-zero + dup1 CONVERT_TO_ASSETS_INNER() // [assets, shares, receiver, owner] + dup1 non_zero jumpi // [assets, shares, receiver, owner] + ZERO_ASSETS(0x00) + non_zero: + + // Call the before withdraw hook + dup2 dup2 BEFORE_WITHDRAW() // [assets, shares, receiver, owner] + + // Burn the shares, input stack: [shares, owner] + dup4 dup3 _BURN() // [assets, shares, receiver, owner] + + // Emit the withdraw event + dup1 0x00 mstore // [assets, shares, receiver, owner] + dup2 0x20 mstore // [assets, shares, receiver, owner] + dup4 dup4 caller // [msg.sender, receiver, owner, assets, shares, receiver, owner] + __EVENT_HASH(Withdraw) // [event_hash, msg.sender, receiver, owner, assets, shares, receiver, owner] + 0x40 0x00 log4 // [assets, shares, receiver, owner] + + // Transfer the assets from the receiver to the vault + // Store the transfer selector in memory + __FUNC_SIG(transfer) // [selector, assets, shares, receiver, owner] + 0xE0 shl // [selector, assets, shares, receiver, owner] + 0x00 mstore // [assets, shares, receiver, owner] + + // Store the receiver in memory as the first arg + dup3 0x04 mstore // [assets, shares, receiver, owner] + + // Store the assets as the second call argument in memory + dup1 0x24 mstore // [assets, shares, receiver, owner] + + // Load the asset as the call destination + _GET_IMMUTABLE(ASSET_OFFSET, 0x80) // [asset, assets, shares, receiver, owner] + // [ADDRESS] + + // Construct the call + 0x00 // [retSize, asset, assets, shares, receiver, owner] + 0x00 // [retOffset, retSize, asset, assets, shares, receiver, owner] + 0x44 // [argSize, retOffset, retSize, asset, assets, shares, receiver, owner] + 0x00 // [argOffset, argSize, retOffset, retSize, asset, assets, shares, receiver, owner] + 0x00 // [value, argOffset, argSize, retOffset, retSize, asset, assets, shares, receiver, owner] + dup6 // [to, value, argOffset, argSize, retOffset, retSize, asset, assets, shares, receiver, owner] + gas // [gas, to, value, argOffset, argSize, retOffset, retSize, asset, assets, shares, receiver, owner] + call // [success, asset, assets, shares, receiver, owner] + + // Verify the call succeeded + success jumpi // [asset, assets, shares, receiver, owner] + 0x00 dup1 revert // [] + success: + + // Clean the stack and return the assets + pop swap4 pop pop pop // [assets] +} + +/// @notice Deposit +/// @notice Deposits the asset in exchange for shares +/// @param {assets} [uint256] The amount of assets to deposit +/// @param {receiver} [address] The address to receive the shares +#define macro ERC4626_DEPOSIT() = takes (0) returns (0) { + 0x24 calldataload // [receiver] + 0x04 calldataload // [assets, receiver] + DEPOSIT_INNER() // [shares] + 0x00 mstore // [] + 0x20 0x00 return // [] +} + +/// @notice Deposit assets into the ERC4626 Vault +#define macro DEPOSIT_INNER() = takes (2) returns (1) { + // Input stack: [assets, receiver] + // Output stack: [shares] + + // Validate that the assets shares are not zero + dup1 // [assets, assets, receiver] + PREVIEW_DEPOSIT_INNER() // [shares, assets, receiver] + dup1 cont jumpi // [shares, assets, receiver] + ZERO_SHARES(0x00) + cont: + + // Store the transferFrom selector in memory + __FUNC_SIG(transferFrom) // [selector, shares, assets, receiver] + 0xE0 shl // [selector, shares, assets, receiver] + 0x00 mstore // [shares, assets, receiver] + + // Store the caller in memory as the first arg + caller 0x04 mstore // [shares, assets, receiver] + + // Store this address as the second call argument in memory + address 0x24 mstore // [shares, assets, receiver] + + // Store assets as the third call argument in memory + dup2 0x44 mstore // [shares, assets, receiver] + + // Load the asset + _GET_IMMUTABLE(ASSET_OFFSET, 0x80) // [asset, shares, assets, receiver] + + // Construct the call + 0x00 // [retSize, asset, shares, assets, receiver] + 0x00 // [retOffset, retSize, asset, shares, assets, receiver] + 0x64 // [argSize, retOffset, retSize, asset, shares, assets, receiver] + 0x00 // [argOffset, argSize, retOffset, retSize, asset, shares, assets, receiver] + 0x00 // [value, argOffset, argSize, retOffset, retSize, asset, shares, assets, receiver] + dup6 // [to, value, argOffset, argSize, retOffset, retSize, asset, shares, assets, receiver] + gas // [gas, to, value, argOffset, argSize, retOffset, retSize, asset, shares, assets, receiver] + call // [success, asset, shares, assets, receiver] + + // Verify the call succeeded + success jumpi // [asset, shares, assets, receiver] + 0x00 dup1 revert // [] + success: + + // Mint to the receiver + pop dup3 dup2 // [shares, receiver, shares, assets, receiver] + + _MINT() // [shares, assets, receiver] + + // Emit the Deposit Event + dup2 0x00 mstore // [shares, assets, receiver] + dup1 0x20 mstore // [shares, assets, receiver] + dup3 caller // [msg.sender, receiver, shares, assets, receiver] + __EVENT_HASH(Deposit) // [event_hash, msg.sender, receiver, shares, assets, receiver] + 0x40 0x00 log3 // [shares, assets, receiver] + + // Call the after deposit hook + dup1 swap2 swap1 // [shares, assets, shares, receiver] + AFTER_DEPOSIT() // [shares, receiver] + + // Return the shares + swap1 pop // [shares] +} + +/// @notice Withdraw +/// @notice Withdraws the shares in exchange for the underlying assets +/// @param {assets} [uint256] The amount of shares to withdraw +/// @param {receiver} [address] The address to receive the assets +/// @param {owner} [address] The address that owns the shares +#define macro ERC4626_WITHDRAW() = takes (0) returns (0) { + 0x44 calldataload // [owner] + 0x24 calldataload // [receiver, owner] + 0x04 calldataload // [assets, receiver, owner] + WITHDRAWAL_INNER() // [shares] + 0x00 mstore // [] + 0x20 0x00 return // [] +} + +/// @notice Withdraws assets from an ERC4626 Vault +#define macro WITHDRAWAL_INNER() = takes (3) returns (1) { + // Input stack: [assets, receiver, owner] + // Output stack: [shares] + + // Get the shares from the assets + dup1 PREVIEW_WITHDRAW_INNER() // [shares, assets, receiver, owner] + + // Skip ahead if msg.sender is the owner + dup4 caller eq owner_jump jumpi // [shares, assets, receiver, owner] + + // Get the allowance[owner][msg.sender] + caller dup5 // [owner, msg.sender, shares, assets, receiver, owner] + [APPROVAL_SLOT] // [slot, owner, msg.sender, shares, assets, receiver, owner] + LOAD_ELEMENT_FROM_KEYS_2D(0x00) // [allowance, shares, assets, receiver, owner] + + // If the allowed is no infinite approval, set to the allowance less shares + dup1 [TYPE_UINT_256_MAX] // [type(uint256).max, allowance, allowance, shares, assets, receiver, owner] + eq infinite jumpi // [allowance, shares, assets, receiver, owner] + + // Set the new allowance + dup2 dup2 sub // [new_allowance, allowance, shares, assets, receiver, owner] + caller dup6 [APPROVAL_SLOT] // [slot, owner, msg.sender, new_allowance, allowance, shares, assets, receiver, owner] + STORE_ELEMENT_FROM_KEYS_2D(0x00) // [allowance, shares, assets, receiver, owner] + + infinite: + pop // [shares, assets, receiver, owner] + + owner_jump: + + // Call the before withdrawal hook + dup1 dup3 // [assets, shares, shares, assets, receiver, owner] + BEFORE_WITHDRAW() // [shares, assets, receiver, owner] + + // Burn the shares + dup4 dup2 // [shares, owner, shares, assets, receiver, owner] + _BURN() // [shares, assets, receiver, owner] + + // Emit the Withdraw Event + dup2 0x00 mstore // [shares, assets, receiver, owner] + dup1 0x20 mstore // [shares, assets, receiver, owner] + dup4 dup3 caller // [msg.sender, assets, owner, shares, assets, receiver, owner] + __EVENT_HASH(Withdraw) // [event_hash, msg.sender, assets, owner, shares, assets, receiver, owner] + 0x40 0x00 log4 // [shares, assets, receiver, owner] + + // Store the transfer selector in memory + __FUNC_SIG(transfer) // [selector, shares, assets, receiver, owner] + 0xE0 shl // [selector, shares, assets, receiver, owner] + 0x00 mstore // [shares, assets, receiver, owner] + + // Store the receiver in memory as the first arg + dup3 0x04 mstore // [shares, assets, receiver, owner] + + // Store this address as the second call argument in memory + dup2 0x24 mstore // [shares, assets, receiver, owner] + + // Load asset from storage + _GET_IMMUTABLE(ASSET_OFFSET, 0x80) // [asset, shares, assets, receiver, owner] + + // Construct the call + 0x00 // [retSize, asset, shares, assets, receiver, owner] + 0x00 // [retOffset, retSize, asset, shares, assets, receiver, owner] + 0x44 // [argSize, retOffset, retSize, asset, shares, assets, receiver, owner] + 0x00 // [argOffset, argSize, retOffset, retSize, asset, shares, assets, receiver, owner] + 0x00 // [value, argOffset, argSize, retOffset, retSize, asset, shares, assets, receiver, owner] + dup6 // [to, value, argOffset, argSize, retOffset, retSize, asset, shares, assets, receiver, owner] + gas // [gas, to, value, argOffset, argSize, retOffset, retSize, asset, shares, assets, receiver, owner] + call // [success, asset, shares, assets, receiver, owner] + + // Verify the call succeeded + success jumpi // [asset, shares, assets, receiver, owner] + 0x00 dup1 revert // [] + success: + + // Return shares + pop // [shares, assets, receiver, owner] + swap3 pop pop pop // [shares] +} + + +// ------------------------------------------------------ +// ACCOUNTING LOGIC +// ------------------------------------------------------ + +// Input Stack: [] +// Output Stack: [total_assets] +/// @notice Returns the total amount of assets in the Vault +/// @notice REQUIRES OVERRIDEN IMPLEMENTATION +// #define macro TOTAL_ASSETS_INNER() = takes (0) returns (1) + +/// @notice Returns the total amount of assets in the Vault +#define macro TOTAL_ASSETS() = takes (0) returns (0) { + TOTAL_ASSETS_INNER() // [total_assets] + 0x00 mstore // [] + 0x20 0x00 return // [] +} + +/// @notice Returns the amount of assets needed to mint the given amount of shares +/// @param {shares} [uint256] The amount of shares to mint +#define macro PREVIEW_MINT() = takes (0) returns (0) { + 0x04 calldataload // [shares] + PREVIEW_MINT_INNER() // [assets] + 0x00 mstore // [] + 0x20 0x00 return // [] +} + +#define macro PREVIEW_MINT_INNER() = takes (1) returns (1) { + // Input Stack: [shares] + // Output Stack: [assets] + + // Load the total supply + [TOTAL_SUPPLY_SLOT] sload // [supply, shares] + + // Return shares if supply is zero + dup1 calculate jumpi // [supply, shares] + pop cont jump // [] + + // Otherwise mul div up + calculate: + + swap1 // [shares, supply] + TOTAL_ASSETS_INNER() swap1 // [shares, total_assets, supply] + MUL_DIV_UP(fail) // [shares] + cont jump + + // Fail with an arithmetic overflow + fail: + [ARITHMETIC_OVERFLOW] PANIC() + + // Resume withdrawal with share count + cont: // [assets] +} + +/// @notice Calculates the amount of shares that would be exchanged for a given amount of assets +/// @param {assets} [uint256] The amount of assets to exchange +#define macro PREVIEW_DEPOSIT() = takes (1) returns (1) { + 0x04 calldataload // [assets] + PREVIEW_DEPOSIT_INNER() // [shares] + 0x00 mstore // [] + 0x20 0x00 return // [] +} + +#define macro PREVIEW_DEPOSIT_INNER() = takes (1) returns (1) { + CONVERT_TO_SHARES_INNER() // [shares] +} + +/// @notice Converts assets to shares +/// @param {assets} [uint256] The amount of assets to convert +#define macro CONVERT_TO_SHARES() = takes (0) returns (0) { + 0x04 calldataload // [assets] + CONVERT_TO_SHARES_INNER() // [shares] + 0x00 mstore // [] + 0x20 0x00 return // [] +} + +#define macro CONVERT_TO_SHARES_INNER() = takes (1) returns (1) { + // Input Stack: [assets] + // Output Stack: [shares] + + [TOTAL_SUPPLY_SLOT] sload // [supply, assets] + + // Return assets if supply is zero + dup1 calculate jumpi // [supply, assets] + pop cont jump // [] + + // Otherwise mul div down + calculate: + + TOTAL_ASSETS_INNER() swap2 // [assets, supply, total_assets] + MUL_DIV_DOWN(fail) // [shares] + cont jump + + // Fail with an arithmetic overflow + fail: + [ARITHMETIC_OVERFLOW] PANIC() + + // Resume withdrawal with share count + cont: // [shares] +} + +/// @notice Converts shares to assets +/// @param {shares} [uint256] The amount of shares to convert +#define macro CONVERT_TO_ASSETS() = takes (0) returns (0) { + 0x04 calldataload // [shares] + CONVERT_TO_ASSETS_INNER() // [assets] + 0x00 mstore // [] + 0x20 0x00 return // [] +} + +#define macro CONVERT_TO_ASSETS_INNER() = takes (1) returns (1) { + // Input Stack: [shares] + // Output Stack: [assets] + + [TOTAL_SUPPLY_SLOT] sload // [supply, shares] + + // Return assets if supply is zero + dup1 calculate jumpi // [supply, shares] + pop cont jump // [] + + // Otherwise mul div down + calculate: + + swap1 // [shares, supply] + TOTAL_ASSETS_INNER() swap1 // [shares, total_assets, supply] + MUL_DIV_DOWN(fail) // [assets] + cont jump + + // Fail with an arithmetic overflow + fail: + [ARITHMETIC_OVERFLOW] PANIC() + + // Resume withdrawal with share count + cont: // [assets] +} + +/// @notice Calculates the amount of shares that would be exchanged for a given amount of assets +/// @param {assets} [uint256] The amount of assets to exchange +#define macro PREVIEW_WITHDRAW() = takes (1) returns (1) { + 0x04 calldataload // [assets] + PREVIEW_WITHDRAW_INNER() // [shares] + 0x00 mstore // [] + 0x20 0x00 return // [] +} + +#define macro PREVIEW_WITHDRAW_INNER() = takes (1) returns (1) { + // Input Stack: [assets] + // Output Stack: [shares] + + [TOTAL_SUPPLY_SLOT] sload // [supply, assets] + + // Return assets if supply is zero + dup1 calculate jumpi // [supply, assets] + pop dont_fail jump // [] + + // Otherwise mul div up + calculate: + + TOTAL_ASSETS_INNER() swap2 // [assets, supply, total_assets] + MUL_DIV_UP(fail) // [shares] + dont_fail jump + + // Fail with an arithmetic overflow + fail: + [ARITHMETIC_OVERFLOW] PANIC() + + // Resume withdrawal with share count + dont_fail: // [shares] +} + +/// @notice Calculates the amount of assets that would be exchanged for a given amount of shares on redemption +/// @param {shares} [uint256] The amount of shares to exchange +#define macro PREVIEW_REDEEM() = takes (0) returns (0) { + 0x04 calldataload // [shares] + CONVERT_TO_ASSETS_INNER() // [assets] + 0x00 mstore // [] + 0x20 0x00 return // [] +} + +// ------------------------------------------------------ +// DEPOSIT/WITHDRAWAL LIMIT LOGIC +// ------------------------------------------------------ + +/// @notice Max Deposit +/// @notice Returns the maximum amount of assets available to deposit +#define macro MAX_DEPOSIT() = takes (0) returns (0) { + [TYPE_UINT_256_MAX] // [type(uint256).max] + 0x00 mstore // [] + 0x20 0x00 return // [] +} + +/// @notice Max Mint +/// @notice Returns the maximum amount of shares available to mint +#define macro MAX_MINT() = takes (0) returns (0) { + [TYPE_UINT_256_MAX] // [type(uint256).max] + 0x00 mstore // [] + 0x20 0x00 return // [] +} + +/// @notice Max Withdraw +/// @notice Returns the maximum amount of assets available to withdraw +/// @param {owner} [address] The address of the account to withdraw assets from +#define macro MAX_WITHDRAW() = takes (0) returns (0) { + 0x04 calldataload // [owner] + [BALANCE_SLOT] sload // [balanceOf[owner]] + CONVERT_TO_ASSETS_INNER() // [assets] + 0x00 mstore // [] + 0x20 0x00 return // [] +} + +/// @notice Max Redeem +/// @notice Returns the maximum amount of shares available to redeem +/// @param {owner} [address] The address of the account to redeem shares from +#define macro MAX_REDEEM() = takes (0) returns (0) { + 0x04 calldataload // [owner] + [BALANCE_SLOT] sload // [balanceOf[owner]] + 0x00 mstore // [] + 0x20 0x00 return // [] +} + +// ------------------------------------------------------ +// INTERNAL HOOKS LOGIC +// ------------------------------------------------------ + +// Input Stack: [assets, shares] +// Output Stack: [] +/// @notice Called before a withdrawal +/// @notice REQUIRES OVERRIDEN IMPLEMENTATION +// #define macro BEFORE_WITHDRAW() = takes (2) returns (0) + +// Input Stack: [assets, shares] +// Output Stack: [] +/// @notice Called after a deposit +/// @notice REQUIRES OVERRIDEN IMPLEMENTATION +// #define macro AFTER_DEPOSIT() = takes (2) returns (0) + +// ------------------------------------------------------ +// DISPATCH LOGIC +// ------------------------------------------------------ + +/// @notice An internal function dispatcher +#define macro ERC4626_MAIN() = takes (1) returns (1) { + // Input stack: [func_selector] + // Output stack: [func_selector] + + dup1 __FUNC_SIG(decimals) eq decimals_jump jumpi // [func_selector] + dup1 __FUNC_SIG(asset) eq asset_jump jumpi // [func_selector] + + dup1 __FUNC_SIG(deposit) eq deposit_jump jumpi // [func_selector] + dup1 __FUNC_SIG(withdraw) eq withdraw_jump jumpi // [func_selector] + dup1 __FUNC_SIG(mint) eq mint_jump jumpi // [func_selector] + dup1 __FUNC_SIG(redeem) eq redeem_jump jumpi // [func_selector] + + dup1 __FUNC_SIG(totalAssets) eq total_assets_jump jumpi // [func_selector] + dup1 __FUNC_SIG(convertToShares) eq convert_to_shares_jump jumpi // [func_selector] + dup1 __FUNC_SIG(convertToAssets) eq convert_to_assets_jump jumpi // [func_selector] + dup1 __FUNC_SIG(previewDeposit) eq preview_deposit_jump jumpi // [func_selector] + dup1 __FUNC_SIG(previewMint) eq preview_mint_jump jumpi // [func_selector] + dup1 __FUNC_SIG(previewWithdraw) eq preview_withdraw_jump jumpi // [func_selector] + dup1 __FUNC_SIG(previewRedeem) eq preview_redeem_jump jumpi // [func_selector] + + dup1 __FUNC_SIG(maxDeposit) eq max_deposit_jump jumpi // [func_selector] + dup1 __FUNC_SIG(maxMint) eq max_mint_jump jumpi // [func_selector] + dup1 __FUNC_SIG(maxWithdraw) eq max_withdraw_jump jumpi // [func_selector] + dup1 __FUNC_SIG(maxRedeem) eq max_redeem_jump jumpi // [func_selector] + + ERC20_MAIN() // [func_selector] + + // Bubble up to the parent macro + no_match jump + + decimals_jump: + ERC4626_DECIMALS() + asset_jump: + ERC4626_ASSET() + + deposit_jump: + ERC4626_DEPOSIT() + withdraw_jump: + ERC4626_WITHDRAW() + mint_jump: + ERC4626_MINT() + redeem_jump: + ERC4626_REDEEM() + + total_assets_jump: + TOTAL_ASSETS() + convert_to_shares_jump: + CONVERT_TO_SHARES() + convert_to_assets_jump: + CONVERT_TO_ASSETS() + preview_deposit_jump: + PREVIEW_DEPOSIT() + preview_mint_jump: + PREVIEW_MINT() + preview_withdraw_jump: + PREVIEW_WITHDRAW() + preview_redeem_jump: + PREVIEW_REDEEM() + + max_deposit_jump: + MAX_DEPOSIT() + max_mint_jump: + MAX_MINT() + max_withdraw_jump: + MAX_WITHDRAW() + max_redeem_jump: + MAX_REDEEM() + + // Resume parent dispatching + no_match: // [func_selector] +} diff --git a/src/utils/__TEMP__ahkbbusaspkdjqohbmhkbfmghcmmpksnCREATE3.huff b/src/utils/__TEMP__ahkbbusaspkdjqohbmhkbfmghcmmpksnCREATE3.huff new file mode 100644 index 00000000..48b6ccf8 --- /dev/null +++ b/src/utils/__TEMP__ahkbbusaspkdjqohbmhkbfmghcmmpksnCREATE3.huff @@ -0,0 +1,177 @@ +#define function deploy(bytes32, bytes, uint256) payable returns (address) +#define function getDeployed(bytes32) view returns (address) + +#define macro CREATE_3_DEPLOY_WRAPPER() = takes (0) returns (0) { + 0x44 calldataload // [value] + 0x24 calldataload // [&creationCode, value] + 0x04 calldataload // [salt, &creationCode, value] + CREATE_3_DEPLOY() // [deployed] + 0x00 mstore // [] + 0x20 0x00 return // [] +} + +#define macro CREATE_3_GET_DEPLOYED_WRAPPER() = takes (0) returns (0) { + 0x04 calldataload // [salt] + CREATE_3_GET_DEPLOYED() // [deployed] + 0x00 mstore // [] + 0x20 0x00 return // [] +} + +#define macro MAIN() = { + pc calldataload 0xe0 shr + + dup1 __FUNC_SIG(deploy) eq deploy_jump jumpi + dup1 __FUNC_SIG(getDeployed) eq get_deployed_jump jumpi + + // Exit if selector does not match + 0x00 dup1 revert + + deploy_jump: + CREATE_3_DEPLOY_WRAPPER() + get_deployed_jump: + CREATE_3_GET_DEPLOYED_WRAPPER() +} + +/// @title Create3 +/// @notice SPDX-License-Identifier: MIT +/// @author Maddiaa +/// @author asnared +/// @notice Deploy to deterministic addresses without an initcode factor +/// @notice Adapted from Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/CREATE3.sol) + +#include "./CommonErrors.huff" + + +// Proxy Constants +#define constant PROXY_BYTECODE = 0x67363d3d37363d34f03d5260086018f3 +#define constant PROXY_BYTECODE_HASH = 0x21c35dbe1b344a2488cf3321d6ce542f8e9f305544ff09e4993a62319a497c1f + +//--------------------------------------------------------------------------------// +// Opcode | Opcode + Arguments | Description | Stack View // +//--------------------------------------------------------------------------------// +// 0x36 | 0x36 | CALLDATASIZE | size // +// 0x3d | 0x3d | RETURNDATASIZE | 0 size // +// 0x3d | 0x3d | RETURNDATASIZE | 0 0 size // +// 0x37 | 0x37 | CALLDATACOPY | // +// 0x36 | 0x36 | CALLDATASIZE | size // +// 0x3d | 0x3d | RETURNDATASIZE | 0 size // +// 0x34 | 0x34 | CALLVALUE | value 0 size // +// 0xf0 | 0xf0 | CREATE | newContract // +//--------------------------------------------------------------------------------// +// Opcode | Opcode + Arguments | Description | Stack View // +//--------------------------------------------------------------------------------// +// 0x67 | 0x67XXXXXXXXXXXXXXXX | PUSH8 bytecode | bytecode // +// 0x3d | 0x3d | RETURNDATASIZE | 0 bytecode // +// 0x52 | 0x52 | MSTORE | // +// 0x60 | 0x6008 | PUSH1 08 | 8 // +// 0x60 | 0x6018 | PUSH1 18 | 24 8 // +// 0xf3 | 0xf3 | RETURN | // +//--------------------------------------------------------------------------------// + +/// @notice Deploy a new contract with our pre-made bytecode via CREATE2 +#define macro CREATE_3_DEPLOY() = takes (3) returns (1) { + // Input Stack: [salt, &creationCode, value] + // Output Stack: [deployed] + + // Create the proxy + dup1 0x10 // [size, salt, salt, &creationCode, value] + + // Shift the proxy bytecode left + [PROXY_BYTECODE] // [bytecode, size, salt, salt, &creationCode, value, bytecode] + 0x80 shl // [RIGHTPAD(bytecode), size, salt, salt, &creationCode, value, bytecode] + 0x00 mstore // [size, salt, salt, &creationCode, value] + 0x00 // [offset, size, salt, salt, &creationCode, value] + 0x00 // [value, offset, size, salt, salt, &creationCode, value] + create2 // [address, salt, &creationCode, value] + + // Check the address of of the proxy is not null + dup1 iszero // [address == 0, address, salt, &creationCode, value] + deployment_failed jumpi // [address, salt, &creationCode, value] + + // Load the length of the creation code + dup3 0x04 add calldataload // [creationCode.length, address, salt, &creationCode, value] + + // Copy the code from calldata to memory at memory position 0x20 + dup1 0x05 shl // [size, creationCode.length, address, salt, &creationCode, value] + dup5 0x24 add // [calldataOffset, size, creationCode.length, address, salt, &creationCode, value] + 0x20 // [destOffset, calldataOffset, size, creationCode.length, address, salt, &creationCode, value] + calldatacopy // [creationCode.length, address, salt, &creationCode, value] + + // Call the proxy with the creation code + 0x20 // [retSize, creationCode.length, address, salt, &creationCode, value] + 0x00 // [retOffset, retSize, creationCode.length, address, salt, &creationCode, value] + dup3 // [argSize, retOffset, retSize, creationCode.length, address, salt, &creationCode, value] + 0x20 // [argOffset, argSize, retOffset, retSize, creationCode.length, address, salt, &creationCode, value] + dup9 // [value, argOffset, argSize, retOffset, retSize, creationCode.length, address, salt, &creationCode, value] + dup7 // [to, value, argOffset, argSize, retOffset, retSize, creationCode.length, address, salt, &creationCode, value] + gas // [gas, to, value, argOffset, argSize, retOffset, retSize, creationCode.length, address, salt, &creationCode, value] + call // [success, creationCode.length, address, salt, &creationCode, value] + iszero // [success == 0, creationCode.length, address, salt, &creationCode, value] + init_failed jumpi // [creationCode.length, address, salt, &creationCode, value] + + // Get the deployed contract using the salt and make sure it has code at the address + dup3 CREATE_3_GET_DEPLOYED() // [deployed, creationCode.length, address, salt, &creationCode, value] + dup1 extcodesize // [deployed == 0, deployed, creationCode.length, address, salt, &creationCode, value] + iszero init_failed jumpi // [deployed, creationCode.length, address, salt, &creationCode, value] + + // Clean up stack and return + swap5 pop pop pop pop pop // [deployed] + done jump + + deployment_failed: + DEPLOYMENT_FAILED(0x00) + init_failed: + INITIALIZATION_FAILED(0x00) + + done: +} + +#define macro CREATE_3_GET_DEPLOYED() = takes (1) returns (1) { + // Input Stack : [salt] + // Output Stack: [deployed_address] + + // Store 0xff | (right_padded_address >> 1) in memory + __RIGHTPAD(0xff) // [rightpad(0xff), salt] + address 0x58 shl // [rightpad(address), rightpad(0xff), salt] + or // [[0xff][address], salt] + 0x00 mstore // [salt] + + // Store the salt in memory at position 0x15 + 0x15 mstore // [] + + // Store the hash in memory at 0x35 + [PROXY_BYTECODE_HASH] // [hash] + 0x35 mstore // [] + + // Hash the memory from 0x00:0x55 + 0x55 0x00 sha3 // [keccak] + + // ---------------------------------------- // + // Memory Layout // + // ---------------------------------------- // + // prefix | address | nonce | empty // + // 0xd694 | | 01 | 000..000 // + // ---------------------------------------- // + + // 0xd6 = 0xc0 (short RLP prefix) + 0x16 (length of: 0x94 ++ proxy ++ 0x01) + // 0x94 = 0x80 + 0x14 (0x14 = the length of an address, 20 bytes, in hex) + + // Clear the top 10 bytes of the hash + 0x60 shl 0x10 shr // [proxy_address] + + // return rpl encoded + __RIGHTPAD(0xd694) // [0xd694, proxy_address] + or // [ [0xd694][proxy_address] ] + + // Append a 0x01 to the end of the address + + 0x01 0x48 shl // [0x01 << 9, [0xd694][proxy_address]] + or // [ [0xd694][proxy_address][01] ] + + // Hash the packed encoding in memory position 0x00 + 0x00 mstore // [] + 0x17 0x00 sha3 // [hash] + + // Clear the top 12 bytes using shifts + 0x60 shl 0x60 shr // [proxy_address] +} diff --git a/src/utils/__TEMP__ajvxrvsbqwgufgegzhdrxxamgnvfwtnzJumpTableUtil.huff b/src/utils/__TEMP__ajvxrvsbqwgufgegzhdrxxamgnvfwtnzJumpTableUtil.huff new file mode 100644 index 00000000..b42ce920 --- /dev/null +++ b/src/utils/__TEMP__ajvxrvsbqwgufgegzhdrxxamgnvfwtnzJumpTableUtil.huff @@ -0,0 +1,149 @@ +#define function getJumpdestMem(uint256) view returns (uint256) +#define function getJumpdestStack(uint256) view returns (uint256) +#define function getJumpdestMemPacked(uint256) view returns (uint256) +#define function getJumpdestStackPacked(uint256) view returns (uint256) + +#define jumptable TEST_TABLE { + test_label_a test_label_b test_label_c test_label_d +} + +#define jumptable__packed TEST_TABLE_PACKED { + test_label_a test_label_b test_label_c test_label_d +} + +#define macro GET_JUMPDEST_MEM_WRAPPER() = takes (0) returns (0) { + __tablestart(TEST_TABLE) // [table_start] + 0x04 calldataload // [n, table_start] + + // Load a jumpdest inside of `TEST_TABLE` at index `n` into + // memory at 0x00. + LOAD_FROM_JT(0x00) // [] + 0x20 0x00 return +} + +#define macro GET_JUMPDEST_STACK_WRAPPER() = takes (0) returns (0) { + __tablestart(TEST_TABLE) // [table_start] + 0x04 calldataload // [n, table_start] + RETRIEVE_FROM_JT() // [jumpdest_pc] + + // Store our jumpdest_pc in memory & return it + 0x00 mstore // [] + 0x20 0x00 return +} + +#define macro GET_JUMPDEST_MEM_PACKED_WRAPPER() = takes (0) returns (0) { + __tablestart(TEST_TABLE_PACKED) // [table_start] + 0x04 calldataload // [n, table_start] + + // Store the retrieved jumpdest at 0x00 in memory. + // Since `LOAD_FROM_PACKED_JT` only retrieves 2 bytes + // from the contract's code in the `codecopy` op, we + // need to pass our desired memory pointer + 0x1e (30 bytes) + LOAD_FROM_PACKED_JT(0x1e) // [] + 0x20 0x00 return +} + +#define macro GET_JUMPDEST_STACK_PACKED_WRAPPER() = takes (0) returns (0) { + __tablestart(TEST_TABLE_PACKED) // [table_start] + 0x04 calldataload // [n, table_start] + RETRIEVE_FROM_PACKED_JT() // [jumpdest_pc] + + // Store our jumpdest_pc in memory & return it + 0x00 mstore // [] + 0x20 0x00 return +} + +#define macro MAIN() = takes (0) returns (0) { + pc calldataload 0xE0 shr + dup1 __FUNC_SIG(getJumpdestMem) eq get_jumpdest_mem jumpi + dup1 __FUNC_SIG(getJumpdestStack) eq get_jumpdest_stack jumpi + dup1 __FUNC_SIG(getJumpdestMemPacked) eq get_jumpdest_mem_packed jumpi + dup1 __FUNC_SIG(getJumpdestStackPacked) eq get_jumpdest_stack_packed jumpi + + // Revert if no function signature matched + test_label_d jump + + get_jumpdest_mem: + GET_JUMPDEST_MEM_WRAPPER() + get_jumpdest_stack: + GET_JUMPDEST_MEM_WRAPPER() + get_jumpdest_mem_packed: + GET_JUMPDEST_MEM_PACKED_WRAPPER() + get_jumpdest_stack_packed: + GET_JUMPDEST_STACK_PACKED_WRAPPER() + + // Test labels included in `TEST_TABLE` + test_label_a: + test_label_b: + test_label_c: + test_label_d: + 0x00 dup1 revert +} + + +/// @title JumpTableUtil +/// @notice SPDX-License-Identifier: MIT +/// @author clabby +/// @notice Utility macros for retrieving jumpdest pcs from jump tables + +/// @notice Loads a jumpdest stored in a jumptable into memory at `mem_ptr` +/// +/// @param mem_ptr The memory location to load the 2 byte jumpdest into +/// @param index The index of the jumpdest within the jumptable +/// @param table_start The offset of the jumptable in the contract's bytecode +#define macro LOAD_FROM_JT(mem_ptr) = takes (2) returns (1) { + // Input stack: [index, table_start] + + 0x05 shl add // [table_start + index * 0x20] + 0x20 swap1 // [table_start + index * 0x20, 0x20] + // [mem_ptr, table_start + index * 0x20, 0x20] + codecopy // [] + + // Return stack: [] +} + +/// @notice Retrieves a jumpdest stored in a jumptable and puts it on the stack +/// +/// @param index The index of the jumpdest within the jumptable +/// @param table_start The offset of the jumptable in the contract's bytecode +#define macro RETRIEVE_FROM_JT() = takes (2) returns (1) { + // Input stack: [index, table_start] + + LOAD_FROM_JT(0x00) // [] + 0x00 mload // [res] + + // Return stack: [res] +} + +/// @notice Loads a jumpdest stored in a packed jumptable into memory at `mem_ptr` +/// @dev This macro only loads 2 bytes from the contract code, so make sure to account +/// for this when passing a `mem_ptr`. I.e., if we want to store the jumpdest pc +/// at offset `x`, we would pass in `x + 0x1e` as the `mem_ptr` argument. +/// +/// @param mem_ptr The memory location to load the 2 byte jumpdest into +/// @param index The index of the jumpdest within the packed jumptable +/// @param table_start The offset of the packed jumptable in the contract's bytecode +#define macro LOAD_FROM_PACKED_JT(mem_ptr) = takes (2) returns (1) { + // Input stack: [index, table_start] + + 0x01 shl add // [table_start + index * 0x02] + 0x02 swap1 // [table_start + index * 0x02, 0x02] + // [mem_ptr, table_start + index * 0x02, 0x02] + codecopy // [] + + // Return stack: [] +} + +/// @notice Retrieves a jumpdest stored in a packed jumptable and puts it on the stack +/// +/// @param index The index of the jumpdest within the packed jumptable +/// @param table_start The offset of the packed jumptable in the contract's bytecode +#define macro RETRIEVE_FROM_PACKED_JT() = takes (2) returns (1) { + // Input stack: [index, table_start] + + LOAD_FROM_PACKED_JT(0x1e) + // [] + 0x00 mload // [res] + + // Return stack: [res] +} diff --git a/src/utils/__TEMP__appuiqwhffqjrpihtljpxmlgbwuzstqlMerkleProofLib.huff b/src/utils/__TEMP__appuiqwhffqjrpihtljpxmlgbwuzstqlMerkleProofLib.huff new file mode 100644 index 00000000..f55d7ee8 --- /dev/null +++ b/src/utils/__TEMP__appuiqwhffqjrpihtljpxmlgbwuzstqlMerkleProofLib.huff @@ -0,0 +1,86 @@ +#define function verifyProof(bytes32, bytes32, bytes32[] calldata) pure returns (bool) + +#define macro VERIFY_PROOF_WRAPPER() = takes (0) returns (0) { + 0x04 calldataload // [root] + 0x24 calldataload // [leaf, root] + 0x64 // [proof_cd_ptr, leaf, root] + VERIFY_PROOF() // [is_valid] + 0x00 mstore // [] + 0x20 0x00 return +} + +#define macro MAIN() = takes (0) returns (0) { + pc calldataload 0xE0 shr + dup1 __FUNC_SIG(verifyProof) eq verifyProof jumpi + + 0x00 dup1 revert + + verifyProof: + VERIFY_PROOF_WRAPPER() +} + + +/// @title MerkleProofLib +/// @notice SPDX-License-Identifier: MIT +/// @author clabby +/// @notice Gas optimized merkle proof verification library +/// @notice Adapted from Solmate (https://github.com/transmissions11/solmate/blob/v7/src/utils/MerkleProofLib.sol) +/// @dev The `proof_cd_ptr` passed via the stack to this macro should point to the offset +/// of the proof array's length in the calldata. This macro assumes that the proof +/// array contains 32 byte values. + +/// @notice Verifies a merkle proof. +/// @param proof_cd_ptr Pointer to the length of the proof array. +/// @param leaf Leaf to prove inclusion of +/// @param root Root of the merkle tree +/// @return is_valid True if the inclusion of `leaf` in the merkle tree represented by +/// `root` was able to be proven, false if not. +#define macro VERIFY_PROOF() = takes (3) returns (1) { + // Input Stack: [proof_cd_ptr, leaf, root] + + // Get ending offset (ptr + 1 + proof_len * 0x20) of proof array + // and its starting offset (ptr + 0x20) + dup1 + 0x20 add + swap1 // [proof_cd_ptr, proof_cd_ptr + 0x20, leaf, root] + calldataload // [proof_arr_len, proof_cd_ptr + 0x20, leaf, root] + 0x05 shl // [proof_arr_len << 5, proof_cd_ptr + 0x20, leaf, root] + dup2 add // [proof_arr_len << 5 + proof_cd_ptr + 0x20, proof_cd_ptr + 0x20, leaf, root] + + // Stack description changed to reflect the vars' respective purposes in the loop + swap1 // [loop_offset, proof_arr_end, computed_hash, root] + + loop: + dup2 dup2 // [loop_offset, proof_arr_end, loop_offset, proof_arr_end, computed_hash, root] + lt // [loop_offset < proof_arr_end, loop_offset, proof_arr_end, computed_hash, root] + // If loop index is >= the proof arr end offset, finish the loop + iszero finish jumpi + + // Load data at proof_arr[loop_offset] + dup1 // [loop_offset, loop_offset, proof_arr_end, computed_hash, root] + calldataload // [proof_arr[loop_offset], loop_offset, proof_arr_end, computed_hash, root] + + dup1 // [proof_arr[loop_offset], proof_arr[loop_offset], loop_offset, proof_arr_end, computed_hash, root] + dup5 // [computed_hash, proof_arr[loop_offset], proof_arr[loop_offset], loop_offset, proof_arr_end, computed_hash, root] + gt // [computed_hash > proof_arr[loop_offset], proof_arr[loop_offset], loop_offset, proof_arr_end, computed_hash, root] + 0x05 shl // [(computed_hash > proof_arr[loop_offset]) << 5, proof_arr[loop_offset], loop_offset, proof_arr_end, computed_hash, root] + + dup5 // [computed_hash, (computed_hash > proof_arr[loop_offset]) << 5, proof_arr[loop_offset], loop_offset, proof_arr_end, computed_hash, root] + dup2 // [(computed_hash > proof_arr[loop_offset]) << 5, computed_hash, (computed_hash > proof_arr[loop_offset]) << 5, proof_arr[loop_offset], loop_offset, proof_arr_end, computed_hash, root] + mstore // [(computed_hash > proof_arr[loop_offset]) << 5, proof_arr[loop_offset], loop_offset, proof_arr_end, computed_hash, root] + + 0x20 xor // [((computed_hash > proof_arr[loop_offset]) << 5) ^ 0x20, proof_arr[loop_offset], loop_offset, proof_arr_end, computed_hash, root] + mstore // [loop_offset, proof_arr_end, computed_hash, root] + + // Compute new hash + 0x40 0x00 sha3 // [computed_hash_new, loop_offset, proof_arr_end, computed_hash, root] + swap3 pop // [loop_offset, proof_arr_end, computed_hash, root] + + // Increment loop offset by 0x20 + 0x20 add // [loop_offset + 0x20, proof_arr_end, computed_hash, root] + + loop jump + finish: + pop pop // [root, computed_hash] + eq // [root == computed_hash] +} \ No newline at end of file diff --git a/src/utils/__TEMP__avabubbndjqnadwlvmuebjtdnnpdjprqConstants.huff b/src/utils/__TEMP__avabubbndjqnadwlvmuebjtdnnpdjprqConstants.huff new file mode 100644 index 00000000..157180e7 --- /dev/null +++ b/src/utils/__TEMP__avabubbndjqnadwlvmuebjtdnnpdjprqConstants.huff @@ -0,0 +1,1789 @@ + +// interface +#define function oneWei() pure returns(uint256) +#define function oneGwei() pure returns(uint256) +#define function oneEther() pure returns(uint256) +#define function oneSeconds() pure returns(uint256) +#define function oneMinutes() pure returns(uint256) +#define function oneHours() pure returns(uint256) +#define function oneDays() pure returns(uint256) +#define function oneWeeks() pure returns(uint256) + +#define function uint256Max() pure returns(uint256) +#define function uint248Max() pure returns(uint256) +#define function uint240Max() pure returns(uint256) +#define function uint232Max() pure returns(uint256) +#define function uint224Max() pure returns(uint256) +#define function uint216Max() pure returns(uint256) +#define function uint208Max() pure returns(uint256) +#define function uint200Max() pure returns(uint256) +#define function uint192Max() pure returns(uint256) +#define function uint184Max() pure returns(uint256) +#define function uint176Max() pure returns(uint256) +#define function uint168Max() pure returns(uint256) +#define function uint160Max() pure returns(uint256) +#define function uint152Max() pure returns(uint256) +#define function uint144Max() pure returns(uint256) +#define function uint136Max() pure returns(uint256) +#define function uint128Max() pure returns(uint256) +#define function uint120Max() pure returns(uint256) +#define function uint112Max() pure returns(uint256) +#define function uint104Max() pure returns(uint256) +#define function uint96Max() pure returns(uint256) +#define function uint88Max() pure returns(uint256) +#define function uint80Max() pure returns(uint256) +#define function uint72Max() pure returns(uint256) +#define function uint64Max() pure returns(uint256) +#define function uint56Max() pure returns(uint256) +#define function uint48Max() pure returns(uint256) +#define function uint40Max() pure returns(uint256) +#define function uint32Max() pure returns(uint256) +#define function uint24Max() pure returns(uint256) +#define function uint16Max() pure returns(uint256) +#define function uint8Max() pure returns(uint256) + +#define function int256Max() pure returns(int256) +#define function int248Max() pure returns(int256) +#define function int240Max() pure returns(int256) +#define function int232Max() pure returns(int256) +#define function int224Max() pure returns(int256) +#define function int216Max() pure returns(int256) +#define function int208Max() pure returns(int256) +#define function int200Max() pure returns(int256) +#define function int192Max() pure returns(int256) +#define function int184Max() pure returns(int256) +#define function int176Max() pure returns(int256) +#define function int168Max() pure returns(int256) +#define function int160Max() pure returns(int256) +#define function int152Max() pure returns(int256) +#define function int144Max() pure returns(int256) +#define function int136Max() pure returns(int256) +#define function int128Max() pure returns(int256) +#define function int120Max() pure returns(int256) +#define function int112Max() pure returns(int256) +#define function int104Max() pure returns(int256) +#define function int96Max() pure returns(int256) +#define function int88Max() pure returns(int256) +#define function int80Max() pure returns(int256) +#define function int72Max() pure returns(int256) +#define function int64Max() pure returns(int256) +#define function int56Max() pure returns(int256) +#define function int48Max() pure returns(int256) +#define function int40Max() pure returns(int256) +#define function int32Max() pure returns(int256) +#define function int24Max() pure returns(int256) +#define function int16Max() pure returns(int256) +#define function int8Max() pure returns(int256) + +#define function int256Min() pure returns(int256) +#define function int248Min() pure returns(int256) +#define function int240Min() pure returns(int256) +#define function int232Min() pure returns(int256) +#define function int224Min() pure returns(int256) +#define function int216Min() pure returns(int256) +#define function int208Min() pure returns(int256) +#define function int200Min() pure returns(int256) +#define function int192Min() pure returns(int256) +#define function int184Min() pure returns(int256) +#define function int176Min() pure returns(int256) +#define function int168Min() pure returns(int256) +#define function int160Min() pure returns(int256) +#define function int152Min() pure returns(int256) +#define function int144Min() pure returns(int256) +#define function int136Min() pure returns(int256) +#define function int128Min() pure returns(int256) +#define function int120Min() pure returns(int256) +#define function int112Min() pure returns(int256) +#define function int104Min() pure returns(int256) +#define function int96Min() pure returns(int256) +#define function int88Min() pure returns(int256) +#define function int80Min() pure returns(int256) +#define function int72Min() pure returns(int256) +#define function int64Min() pure returns(int256) +#define function int56Min() pure returns(int256) +#define function int48Min() pure returns(int256) +#define function int40Min() pure returns(int256) +#define function int32Min() pure returns(int256) +#define function int24Min() pure returns(int256) +#define function int16Min() pure returns(int256) +#define function int8Min() pure returns(int256) + +#define function multiWei(uint256) pure returns(uint256) +#define function multiGwei(uint256) pure returns(uint256) +#define function multiEther(uint256) pure returns(uint256) +#define function multiSeconds(uint256) pure returns(uint256) +#define function multiMinutes(uint256) pure returns(uint256) +#define function multiHours(uint256) pure returns(uint256) +#define function multiDays(uint256) pure returns(uint256) +#define function multiWeeks(uint256) pure returns(uint256) + + +#define macro ONE_WEI() = takes(0) returns(0) { + [__ONE_WEI] 0x00 mstore + 0x20 0x00 return +} + +#define macro ONE_GWEI() = takes(0) returns(0) { + [__ONE_GWEI] 0x00 mstore + 0x20 0x00 return +} + +#define macro ONE_ETHER() = takes(0) returns(0) { + [__ONE_ETHER] 0x00 mstore + 0x20 0x00 return +} + +#define macro ONE_SECONDS() = takes(0) returns(0) { + [__ONE_SECONDS] 0x00 mstore + 0x20 0x00 return +} + +#define macro ONE_MINUTES() = takes(0) returns(0) { + [__ONE_MINUTES] 0x00 mstore + 0x20 0x00 return +} + +#define macro ONE_HOURS() = takes(0) returns(0) { + [__ONE_HOURS] 0x00 mstore + 0x20 0x00 return +} + +#define macro ONE_DAYS() = takes(0) returns(0) { + [__ONE_DAYS] 0x00 mstore + 0x20 0x00 return +} + +#define macro ONE_WEEKS() = takes(0) returns(0) { + [__ONE_WEEKS] 0x00 mstore + 0x20 0x00 return +} + + + +#define macro UINT256_MAX() = takes(0) returns(0) { + [__UINT256_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro UINT248_MAX() = takes(0) returns(0) { + [__UINT248_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro UINT240_MAX() = takes(0) returns(0) { + [__UINT240_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro UINT232_MAX() = takes(0) returns(0) { + [__UINT232_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro UINT224_MAX() = takes(0) returns(0) { + [__UINT224_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro UINT216_MAX() = takes(0) returns(0) { + [__UINT216_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro UINT208_MAX() = takes(0) returns(0) { + [__UINT208_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro UINT200_MAX() = takes(0) returns(0) { + [__UINT200_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro UINT192_MAX() = takes(0) returns(0) { + [__UINT192_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro UINT184_MAX() = takes(0) returns(0) { + [__UINT184_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro UINT176_MAX() = takes(0) returns(0) { + [__UINT176_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro UINT168_MAX() = takes(0) returns(0) { + [__UINT168_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro UINT160_MAX() = takes(0) returns(0) { + [__UINT160_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro UINT152_MAX() = takes(0) returns(0) { + [__UINT152_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro UINT144_MAX() = takes(0) returns(0) { + [__UINT144_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro UINT136_MAX() = takes(0) returns(0) { + [__UINT136_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro UINT128_MAX() = takes(0) returns(0) { + [__UINT128_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro UINT120_MAX() = takes(0) returns(0) { + [__UINT120_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro UINT112_MAX() = takes(0) returns(0) { + [__UINT112_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro UINT104_MAX() = takes(0) returns(0) { + [__UINT104_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro UINT96_MAX() = takes(0) returns(0) { + [__UINT96_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro UINT88_MAX() = takes(0) returns(0) { + [__UINT88_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro UINT80_MAX() = takes(0) returns(0) { + [__UINT80_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro UINT72_MAX() = takes(0) returns(0) { + [__UINT72_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro UINT64_MAX() = takes(0) returns(0) { + [__UINT64_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro UINT56_MAX() = takes(0) returns(0) { + [__UINT56_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro UINT48_MAX() = takes(0) returns(0) { + [__UINT48_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro UINT40_MAX() = takes(0) returns(0) { + [__UINT40_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro UINT32_MAX() = takes(0) returns(0) { + [__UINT32_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro UINT24_MAX() = takes(0) returns(0) { + [__UINT24_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro UINT16_MAX() = takes(0) returns(0) { + [__UINT16_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro UINT8_MAX() = takes(0) returns(0) { + [__UINT8_MAX] 0x00 mstore + 0x20 0x00 return +} + + + + + + +#define macro INT256_MAX() = takes(0) returns(0) { + [__INT256_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT248_MAX() = takes(0) returns(0) { + [__INT248_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT240_MAX() = takes(0) returns(0) { + [__INT240_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT232_MAX() = takes(0) returns(0) { + [__INT232_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT224_MAX() = takes(0) returns(0) { + [__INT224_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT216_MAX() = takes(0) returns(0) { + [__INT216_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT208_MAX() = takes(0) returns(0) { + [__INT208_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT200_MAX() = takes(0) returns(0) { + [__INT200_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT192_MAX() = takes(0) returns(0) { + [__INT192_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT184_MAX() = takes(0) returns(0) { + [__INT184_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT176_MAX() = takes(0) returns(0) { + [__INT176_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT168_MAX() = takes(0) returns(0) { + [__INT168_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT160_MAX() = takes(0) returns(0) { + [__INT160_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT152_MAX() = takes(0) returns(0) { + [__INT152_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT144_MAX() = takes(0) returns(0) { + [__INT144_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT136_MAX() = takes(0) returns(0) { + [__INT136_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT128_MAX() = takes(0) returns(0) { + [__INT128_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT120_MAX() = takes(0) returns(0) { + [__INT120_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT112_MAX() = takes(0) returns(0) { + [__INT112_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT104_MAX() = takes(0) returns(0) { + [__INT104_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT96_MAX() = takes(0) returns(0) { + [__INT96_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT88_MAX() = takes(0) returns(0) { + [__INT88_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT80_MAX() = takes(0) returns(0) { + [__INT80_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT72_MAX() = takes(0) returns(0) { + [__INT72_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT64_MAX() = takes(0) returns(0) { + [__INT64_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT56_MAX() = takes(0) returns(0) { + [__INT56_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT48_MAX() = takes(0) returns(0) { + [__INT48_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT40_MAX() = takes(0) returns(0) { + [__INT40_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT32_MAX() = takes(0) returns(0) { + [__INT32_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT24_MAX() = takes(0) returns(0) { + [__INT24_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT16_MAX() = takes(0) returns(0) { + [__INT16_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT8_MAX() = takes(0) returns(0) { + [__INT8_MAX] 0x00 mstore + 0x20 0x00 return +} + + + + + + +#define macro INT256_MIN() = takes(0) returns(0) { + [__INT256_MIN] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT248_MIN() = takes(0) returns(0) { + [__INT248_MIN] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT240_MIN() = takes(0) returns(0) { + [__INT240_MIN] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT232_MIN() = takes(0) returns(0) { + [__INT232_MIN] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT224_MIN() = takes(0) returns(0) { + [__INT224_MIN] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT216_MIN() = takes(0) returns(0) { + [__INT216_MIN] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT208_MIN() = takes(0) returns(0) { + [__INT208_MIN] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT200_MIN() = takes(0) returns(0) { + [__INT200_MIN] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT192_MIN() = takes(0) returns(0) { + [__INT192_MIN] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT184_MIN() = takes(0) returns(0) { + [__INT184_MIN] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT176_MIN() = takes(0) returns(0) { + [__INT176_MIN] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT168_MIN() = takes(0) returns(0) { + [__INT168_MIN] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT160_MIN() = takes(0) returns(0) { + [__INT160_MIN] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT152_MIN() = takes(0) returns(0) { + [__INT152_MIN] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT144_MIN() = takes(0) returns(0) { + [__INT144_MIN] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT136_MIN() = takes(0) returns(0) { + [__INT136_MIN] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT128_MIN() = takes(0) returns(0) { + [__INT128_MIN] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT120_MIN() = takes(0) returns(0) { + [__INT120_MIN] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT112_MIN() = takes(0) returns(0) { + [__INT112_MIN] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT104_MIN() = takes(0) returns(0) { + [__INT104_MIN] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT96_MIN() = takes(0) returns(0) { + [__INT96_MIN] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT88_MIN() = takes(0) returns(0) { + [__INT88_MIN] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT80_MIN() = takes(0) returns(0) { + [__INT80_MIN] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT72_MIN() = takes(0) returns(0) { + [__INT72_MIN] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT64_MIN() = takes(0) returns(0) { + [__INT64_MIN] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT56_MIN() = takes(0) returns(0) { + [__INT56_MIN] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT48_MIN() = takes(0) returns(0) { + [__INT48_MIN] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT40_MIN() = takes(0) returns(0) { + [__INT40_MIN] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT32_MIN() = takes(0) returns(0) { + [__INT32_MIN] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT24_MIN() = takes(0) returns(0) { + [__INT24_MIN] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT16_MIN() = takes(0) returns(0) { + [__INT16_MIN] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT8_MIN() = takes(0) returns(0) { + [__INT8_MIN] 0x00 mstore + 0x20 0x00 return +} + + + + +#define macro MULTI_WEI() = takes(0) returns(0) { + 0x04 calldataload __WEI() 0x00 mstore + 0x20 0x00 return +} + +#define macro MULTI_GWEI() = takes(0) returns(0) { + 0x04 calldataload __GWEI() 0x00 mstore + 0x20 0x00 return +} + +#define macro MULTI_ETHER() = takes(0) returns(0) { + 0x04 calldataload __ETHER() 0x00 mstore + 0x20 0x00 return +} + +#define macro MULTI_SECONDS() = takes(0) returns(0) { + 0x04 calldataload __SECONDS() 0x00 mstore + 0x20 0x00 return +} + +#define macro MULTI_MINUTES() = takes(0) returns(0) { + 0x04 calldataload __MINUTES() 0x00 mstore + 0x20 0x00 return +} + +#define macro MULTI_HOURS() = takes(0) returns(0) { + 0x04 calldataload __HOURS() 0x00 mstore + 0x20 0x00 return +} + +#define macro MULTI_DAYS() = takes(0) returns(0) { + 0x04 calldataload __DAYS() 0x00 mstore + 0x20 0x00 return +} + +#define macro MULTI_WEEKS() = takes(0) returns(0) { + 0x04 calldataload __WEEKS() 0x00 mstore + 0x20 0x00 return +} + + + + + + + + + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // Identify which function is being called. + // [func sig] + 0x00 calldataload 0xE0 shr + + + // function int104Max() pure returns (int256) + dup1 __FUNC_SIG(int104Max) eq int104MaxJump jumpi + + + // function int104Min() pure returns (int256) + dup1 __FUNC_SIG(int104Min) eq int104MinJump jumpi + + + // function int112Max() pure returns (int256) + dup1 __FUNC_SIG(int112Max) eq int112MaxJump jumpi + + + // function int112Min() pure returns (int256) + dup1 __FUNC_SIG(int112Min) eq int112MinJump jumpi + + + // function int120Max() pure returns (int256) + dup1 __FUNC_SIG(int120Max) eq int120MaxJump jumpi + + + // function int120Min() pure returns (int256) + dup1 __FUNC_SIG(int120Min) eq int120MinJump jumpi + + + // function int128Max() pure returns (int256) + dup1 __FUNC_SIG(int128Max) eq int128MaxJump jumpi + + + // function int128Min() pure returns (int256) + dup1 __FUNC_SIG(int128Min) eq int128MinJump jumpi + + + // function int136Max() pure returns (int256) + dup1 __FUNC_SIG(int136Max) eq int136MaxJump jumpi + + + // function int136Min() pure returns (int256) + dup1 __FUNC_SIG(int136Min) eq int136MinJump jumpi + + + // function int144Max() pure returns (int256) + dup1 __FUNC_SIG(int144Max) eq int144MaxJump jumpi + + + // function int144Min() pure returns (int256) + dup1 __FUNC_SIG(int144Min) eq int144MinJump jumpi + + + // function int152Max() pure returns (int256) + dup1 __FUNC_SIG(int152Max) eq int152MaxJump jumpi + + + // function int152Min() pure returns (int256) + dup1 __FUNC_SIG(int152Min) eq int152MinJump jumpi + + + // function int160Max() pure returns (int256) + dup1 __FUNC_SIG(int160Max) eq int160MaxJump jumpi + + + // function int160Min() pure returns (int256) + dup1 __FUNC_SIG(int160Min) eq int160MinJump jumpi + + + // function int168Max() pure returns (int256) + dup1 __FUNC_SIG(int168Max) eq int168MaxJump jumpi + + + // function int168Min() pure returns (int256) + dup1 __FUNC_SIG(int168Min) eq int168MinJump jumpi + + + // function int16Max() pure returns (int256) + dup1 __FUNC_SIG(int16Max) eq int16MaxJump jumpi + + + // function int16Min() pure returns (int256) + dup1 __FUNC_SIG(int16Min) eq int16MinJump jumpi + + + // function int176Max() pure returns (int256) + dup1 __FUNC_SIG(int176Max) eq int176MaxJump jumpi + + + // function int176Min() pure returns (int256) + dup1 __FUNC_SIG(int176Min) eq int176MinJump jumpi + + + // function int184Max() pure returns (int256) + dup1 __FUNC_SIG(int184Max) eq int184MaxJump jumpi + + + // function int184Min() pure returns (int256) + dup1 __FUNC_SIG(int184Min) eq int184MinJump jumpi + + + // function int192Max() pure returns (int256) + dup1 __FUNC_SIG(int192Max) eq int192MaxJump jumpi + + + // function int192Min() pure returns (int256) + dup1 __FUNC_SIG(int192Min) eq int192MinJump jumpi + + + // function int200Max() pure returns (int256) + dup1 __FUNC_SIG(int200Max) eq int200MaxJump jumpi + + + // function int200Min() pure returns (int256) + dup1 __FUNC_SIG(int200Min) eq int200MinJump jumpi + + + // function int208Max() pure returns (int256) + dup1 __FUNC_SIG(int208Max) eq int208MaxJump jumpi + + + // function int208Min() pure returns (int256) + dup1 __FUNC_SIG(int208Min) eq int208MinJump jumpi + + + // function int216Max() pure returns (int256) + dup1 __FUNC_SIG(int216Max) eq int216MaxJump jumpi + + + // function int216Min() pure returns (int256) + dup1 __FUNC_SIG(int216Min) eq int216MinJump jumpi + + + // function int224Max() pure returns (int256) + dup1 __FUNC_SIG(int224Max) eq int224MaxJump jumpi + + + // function int224Min() pure returns (int256) + dup1 __FUNC_SIG(int224Min) eq int224MinJump jumpi + + + // function int232Max() pure returns (int256) + dup1 __FUNC_SIG(int232Max) eq int232MaxJump jumpi + + + // function int232Min() pure returns (int256) + dup1 __FUNC_SIG(int232Min) eq int232MinJump jumpi + + + // function int240Max() pure returns (int256) + dup1 __FUNC_SIG(int240Max) eq int240MaxJump jumpi + + + // function int240Min() pure returns (int256) + dup1 __FUNC_SIG(int240Min) eq int240MinJump jumpi + + + // function int248Max() pure returns (int256) + dup1 __FUNC_SIG(int248Max) eq int248MaxJump jumpi + + + // function int248Min() pure returns (int256) + dup1 __FUNC_SIG(int248Min) eq int248MinJump jumpi + + + // function int24Max() pure returns (int256) + dup1 __FUNC_SIG(int24Max) eq int24MaxJump jumpi + + + // function int24Min() pure returns (int256) + dup1 __FUNC_SIG(int24Min) eq int24MinJump jumpi + + + // function int256Max() pure returns (int256) + dup1 __FUNC_SIG(int256Max) eq int256MaxJump jumpi + + + // function int256Min() pure returns (int256) + dup1 __FUNC_SIG(int256Min) eq int256MinJump jumpi + + + // function int32Max() pure returns (int256) + dup1 __FUNC_SIG(int32Max) eq int32MaxJump jumpi + + + // function int32Min() pure returns (int256) + dup1 __FUNC_SIG(int32Min) eq int32MinJump jumpi + + + // function int40Max() pure returns (int256) + dup1 __FUNC_SIG(int40Max) eq int40MaxJump jumpi + + + // function int40Min() pure returns (int256) + dup1 __FUNC_SIG(int40Min) eq int40MinJump jumpi + + + // function int48Max() pure returns (int256) + dup1 __FUNC_SIG(int48Max) eq int48MaxJump jumpi + + + // function int48Min() pure returns (int256) + dup1 __FUNC_SIG(int48Min) eq int48MinJump jumpi + + + // function int56Max() pure returns (int256) + dup1 __FUNC_SIG(int56Max) eq int56MaxJump jumpi + + + // function int56Min() pure returns (int256) + dup1 __FUNC_SIG(int56Min) eq int56MinJump jumpi + + + // function int64Max() pure returns (int256) + dup1 __FUNC_SIG(int64Max) eq int64MaxJump jumpi + + + // function int64Min() pure returns (int256) + dup1 __FUNC_SIG(int64Min) eq int64MinJump jumpi + + + // function int72Max() pure returns (int256) + dup1 __FUNC_SIG(int72Max) eq int72MaxJump jumpi + + + // function int72Min() pure returns (int256) + dup1 __FUNC_SIG(int72Min) eq int72MinJump jumpi + + + // function int80Max() pure returns (int256) + dup1 __FUNC_SIG(int80Max) eq int80MaxJump jumpi + + + // function int80Min() pure returns (int256) + dup1 __FUNC_SIG(int80Min) eq int80MinJump jumpi + + + // function int88Max() pure returns (int256) + dup1 __FUNC_SIG(int88Max) eq int88MaxJump jumpi + + + // function int88Min() pure returns (int256) + dup1 __FUNC_SIG(int88Min) eq int88MinJump jumpi + + + // function int8Max() pure returns (int256) + dup1 __FUNC_SIG(int8Max) eq int8MaxJump jumpi + + + // function int8Min() pure returns (int256) + dup1 __FUNC_SIG(int8Min) eq int8MinJump jumpi + + + // function int96Max() pure returns (int256) + dup1 __FUNC_SIG(int96Max) eq int96MaxJump jumpi + + + // function int96Min() pure returns (int256) + dup1 __FUNC_SIG(int96Min) eq int96MinJump jumpi + + + // function multiDays(uint256) pure returns (uint256) + dup1 __FUNC_SIG(multiDays) eq multiDaysJump jumpi + + + // function multiEther(uint256) pure returns (uint256) + dup1 __FUNC_SIG(multiEther) eq multiEtherJump jumpi + + + // function multiGwei(uint256) pure returns (uint256) + dup1 __FUNC_SIG(multiGwei) eq multiGweiJump jumpi + + + // function multiHours(uint256) pure returns (uint256) + dup1 __FUNC_SIG(multiHours) eq multiHoursJump jumpi + + + // function multiMinutes(uint256) pure returns (uint256) + dup1 __FUNC_SIG(multiMinutes) eq multiMinutesJump jumpi + + + // function multiSeconds(uint256) pure returns (uint256) + dup1 __FUNC_SIG(multiSeconds) eq multiSecondsJump jumpi + + + // function multiWeeks(uint256) pure returns (uint256) + dup1 __FUNC_SIG(multiWeeks) eq multiWeeksJump jumpi + + + // function multiWei(uint256) pure returns (uint256) + dup1 __FUNC_SIG(multiWei) eq multiWeiJump jumpi + + + // function oneDays() pure returns (uint256) + dup1 __FUNC_SIG(oneDays) eq oneDaysJump jumpi + + + // function oneEther() pure returns (uint256) + dup1 __FUNC_SIG(oneEther) eq oneEtherJump jumpi + + + // function oneGwei() pure returns (uint256) + dup1 __FUNC_SIG(oneGwei) eq oneGweiJump jumpi + + + // function oneHours() pure returns (uint256) + dup1 __FUNC_SIG(oneHours) eq oneHoursJump jumpi + + + // function oneMinutes() pure returns (uint256) + dup1 __FUNC_SIG(oneMinutes) eq oneMinutesJump jumpi + + + // function oneSeconds() pure returns (uint256) + dup1 __FUNC_SIG(oneSeconds) eq oneSecondsJump jumpi + + + // function oneWeeks() pure returns (uint256) + dup1 __FUNC_SIG(oneWeeks) eq oneWeeksJump jumpi + + + // function oneWei() pure returns (uint256) + dup1 __FUNC_SIG(oneWei) eq oneWeiJump jumpi + + + // function uint104Max() pure returns (uint256) + dup1 __FUNC_SIG(uint104Max) eq uint104MaxJump jumpi + + + // function uint112Max() pure returns (uint256) + dup1 __FUNC_SIG(uint112Max) eq uint112MaxJump jumpi + + + // function uint120Max() pure returns (uint256) + dup1 __FUNC_SIG(uint120Max) eq uint120MaxJump jumpi + + + // function uint128Max() pure returns (uint256) + dup1 __FUNC_SIG(uint128Max) eq uint128MaxJump jumpi + + + // function uint136Max() pure returns (uint256) + dup1 __FUNC_SIG(uint136Max) eq uint136MaxJump jumpi + + + // function uint144Max() pure returns (uint256) + dup1 __FUNC_SIG(uint144Max) eq uint144MaxJump jumpi + + + // function uint152Max() pure returns (uint256) + dup1 __FUNC_SIG(uint152Max) eq uint152MaxJump jumpi + + + // function uint160Max() pure returns (uint256) + dup1 __FUNC_SIG(uint160Max) eq uint160MaxJump jumpi + + + // function uint168Max() pure returns (uint256) + dup1 __FUNC_SIG(uint168Max) eq uint168MaxJump jumpi + + + // function uint16Max() pure returns (uint256) + dup1 __FUNC_SIG(uint16Max) eq uint16MaxJump jumpi + + + // function uint176Max() pure returns (uint256) + dup1 __FUNC_SIG(uint176Max) eq uint176MaxJump jumpi + + + // function uint184Max() pure returns (uint256) + dup1 __FUNC_SIG(uint184Max) eq uint184MaxJump jumpi + + + // function uint192Max() pure returns (uint256) + dup1 __FUNC_SIG(uint192Max) eq uint192MaxJump jumpi + + + // function uint200Max() pure returns (uint256) + dup1 __FUNC_SIG(uint200Max) eq uint200MaxJump jumpi + + + // function uint208Max() pure returns (uint256) + dup1 __FUNC_SIG(uint208Max) eq uint208MaxJump jumpi + + + // function uint216Max() pure returns (uint256) + dup1 __FUNC_SIG(uint216Max) eq uint216MaxJump jumpi + + + // function uint224Max() pure returns (uint256) + dup1 __FUNC_SIG(uint224Max) eq uint224MaxJump jumpi + + + // function uint232Max() pure returns (uint256) + dup1 __FUNC_SIG(uint232Max) eq uint232MaxJump jumpi + + + // function uint240Max() pure returns (uint256) + dup1 __FUNC_SIG(uint240Max) eq uint240MaxJump jumpi + + + // function uint248Max() pure returns (uint256) + dup1 __FUNC_SIG(uint248Max) eq uint248MaxJump jumpi + + + // function uint24Max() pure returns (uint256) + dup1 __FUNC_SIG(uint24Max) eq uint24MaxJump jumpi + + + // function uint256Max() pure returns (uint256) + dup1 __FUNC_SIG(uint256Max) eq uint256MaxJump jumpi + + + // function uint32Max() pure returns (uint256) + dup1 __FUNC_SIG(uint32Max) eq uint32MaxJump jumpi + + + // function uint40Max() pure returns (uint256) + dup1 __FUNC_SIG(uint40Max) eq uint40MaxJump jumpi + + + // function uint48Max() pure returns (uint256) + dup1 __FUNC_SIG(uint48Max) eq uint48MaxJump jumpi + + + // function uint56Max() pure returns (uint256) + dup1 __FUNC_SIG(uint56Max) eq uint56MaxJump jumpi + + + // function uint64Max() pure returns (uint256) + dup1 __FUNC_SIG(uint64Max) eq uint64MaxJump jumpi + + + // function uint72Max() pure returns (uint256) + dup1 __FUNC_SIG(uint72Max) eq uint72MaxJump jumpi + + + // function uint80Max() pure returns (uint256) + dup1 __FUNC_SIG(uint80Max) eq uint80MaxJump jumpi + + + // function uint88Max() pure returns (uint256) + dup1 __FUNC_SIG(uint88Max) eq uint88MaxJump jumpi + + + // function uint8Max() pure returns (uint256) + dup1 __FUNC_SIG(uint8Max) eq uint8MaxJump jumpi + + + // function uint96Max() pure returns (uint256) + dup1 __FUNC_SIG(uint96Max) eq uint96MaxJump jumpi + + not_found: + // Revert if no match is found. + 0x00 dup1 revert + + + // function uint168Max() pure returns (uint256) + uint168MaxJump: + UINT168_MAX() + + // function int184Max() pure returns (int256) + int184MaxJump: + INT184_MAX() + + // function int40Max() pure returns (int256) + int40MaxJump: + INT40_MAX() + + // function oneWeeks() pure returns (uint256) + oneWeeksJump: + ONE_WEEKS() + + // function uint160Max() pure returns (uint256) + uint160MaxJump: + UINT160_MAX() + + // function int176Min() pure returns (int256) + int176MinJump: + INT176_MIN() + + // function int88Max() pure returns (int256) + int88MaxJump: + INT88_MAX() + + // function int168Min() pure returns (int256) + int168MinJump: + INT168_MIN() + + // function int208Min() pure returns (int256) + int208MinJump: + INT208_MIN() + + // function uint104Max() pure returns (uint256) + uint104MaxJump: + UINT104_MAX() + + // function int24Min() pure returns (int256) + int24MinJump: + INT24_MIN() + + // function int112Min() pure returns (int256) + int112MinJump: + INT112_MIN() + + // function int96Max() pure returns (int256) + int96MaxJump: + INT96_MAX() + + // function int96Min() pure returns (int256) + int96MinJump: + INT96_MIN() + + // function uint128Max() pure returns (uint256) + uint128MaxJump: + UINT128_MAX() + + // function uint200Max() pure returns (uint256) + uint200MaxJump: + UINT200_MAX() + + // function oneHours() pure returns (uint256) + oneHoursJump: + ONE_HOURS() + + // function int144Min() pure returns (int256) + int144MinJump: + INT144_MIN() + + // function uint24Max() pure returns (uint256) + uint24MaxJump: + UINT24_MAX() + + // function uint120Max() pure returns (uint256) + uint120MaxJump: + UINT120_MAX() + + // function int256Max() pure returns (int256) + int256MaxJump: + INT256_MAX() + + // function int136Max() pure returns (int256) + int136MaxJump: + INT136_MAX() + + // function int216Max() pure returns (int256) + int216MaxJump: + INT216_MAX() + + // function int144Max() pure returns (int256) + int144MaxJump: + INT144_MAX() + + // function int72Min() pure returns (int256) + int72MinJump: + INT72_MIN() + + // function oneWei() pure returns (uint256) + oneWeiJump: + ONE_WEI() + + // function multiDays(uint256) pure returns (uint256) + multiDaysJump: + MULTI_DAYS() + + // function int64Min() pure returns (int256) + int64MinJump: + INT64_MIN() + + // function uint248Max() pure returns (uint256) + uint248MaxJump: + UINT248_MAX() + + // function int24Max() pure returns (int256) + int24MaxJump: + INT24_MAX() + + // function uint176Max() pure returns (uint256) + uint176MaxJump: + UINT176_MAX() + + // function int32Max() pure returns (int256) + int32MaxJump: + INT32_MAX() + + // function int232Max() pure returns (int256) + int232MaxJump: + INT232_MAX() + + // function int48Min() pure returns (int256) + int48MinJump: + INT48_MIN() + + // function multiSeconds(uint256) pure returns (uint256) + multiSecondsJump: + MULTI_SECONDS() + + // function int224Min() pure returns (int256) + int224MinJump: + INT224_MIN() + + // function int216Min() pure returns (int256) + int216MinJump: + INT216_MIN() + + // function int88Min() pure returns (int256) + int88MinJump: + INT88_MIN() + + // function uint136Max() pure returns (uint256) + uint136MaxJump: + UINT136_MAX() + + // function int248Min() pure returns (int256) + int248MinJump: + INT248_MIN() + + // function int176Max() pure returns (int256) + int176MaxJump: + INT176_MAX() + + // function uint8Max() pure returns (uint256) + uint8MaxJump: + UINT8_MAX() + + // function int56Max() pure returns (int256) + int56MaxJump: + INT56_MAX() + + // function int80Min() pure returns (int256) + int80MinJump: + INT80_MIN() + + // function int200Min() pure returns (int256) + int200MinJump: + INT200_MIN() + + // function uint48Max() pure returns (uint256) + uint48MaxJump: + UINT48_MAX() + + // function int192Max() pure returns (int256) + int192MaxJump: + INT192_MAX() + + // function int208Max() pure returns (int256) + int208MaxJump: + INT208_MAX() + + // function int40Min() pure returns (int256) + int40MinJump: + INT40_MIN() + + // function int192Min() pure returns (int256) + int192MinJump: + INT192_MIN() + + // function int64Max() pure returns (int256) + int64MaxJump: + INT64_MAX() + + // function multiHours(uint256) pure returns (uint256) + multiHoursJump: + MULTI_HOURS() + + // function int16Max() pure returns (int256) + int16MaxJump: + INT16_MAX() + + // function multiEther(uint256) pure returns (uint256) + multiEtherJump: + MULTI_ETHER() + + // function uint64Max() pure returns (uint256) + uint64MaxJump: + UINT64_MAX() + + // function uint216Max() pure returns (uint256) + uint216MaxJump: + UINT216_MAX() + + // function int248Max() pure returns (int256) + int248MaxJump: + INT248_MAX() + + // function int184Min() pure returns (int256) + int184MinJump: + INT184_MIN() + + // function oneGwei() pure returns (uint256) + oneGweiJump: + ONE_GWEI() + + // function int136Min() pure returns (int256) + int136MinJump: + INT136_MIN() + + // function int104Min() pure returns (int256) + int104MinJump: + INT104_MIN() + + // function uint40Max() pure returns (uint256) + uint40MaxJump: + UINT40_MAX() + + // function uint96Max() pure returns (uint256) + uint96MaxJump: + UINT96_MAX() + + // function multiMinutes(uint256) pure returns (uint256) + multiMinutesJump: + MULTI_MINUTES() + + // function uint72Max() pure returns (uint256) + uint72MaxJump: + UINT72_MAX() + + // function int56Min() pure returns (int256) + int56MinJump: + INT56_MIN() + + // function multiGwei(uint256) pure returns (uint256) + multiGweiJump: + MULTI_GWEI() + + // function int232Min() pure returns (int256) + int232MinJump: + INT232_MIN() + + // function uint224Max() pure returns (uint256) + uint224MaxJump: + UINT224_MAX() + + // function uint80Max() pure returns (uint256) + uint80MaxJump: + UINT80_MAX() + + // function int16Min() pure returns (int256) + int16MinJump: + INT16_MIN() + + // function int120Max() pure returns (int256) + int120MaxJump: + INT120_MAX() + + // function uint152Max() pure returns (uint256) + uint152MaxJump: + UINT152_MAX() + + // function multiWei(uint256) pure returns (uint256) + multiWeiJump: + MULTI_WEI() + + // function int200Max() pure returns (int256) + int200MaxJump: + INT200_MAX() + + // function uint144Max() pure returns (uint256) + uint144MaxJump: + UINT144_MAX() + + // function uint32Max() pure returns (uint256) + uint32MaxJump: + UINT32_MAX() + + // function uint184Max() pure returns (uint256) + uint184MaxJump: + UINT184_MAX() + + // function int128Min() pure returns (int256) + int128MinJump: + INT128_MIN() + + // function uint16Max() pure returns (uint256) + uint16MaxJump: + UINT16_MAX() + + // function int160Max() pure returns (int256) + int160MaxJump: + INT160_MAX() + + // function uint208Max() pure returns (uint256) + uint208MaxJump: + UINT208_MAX() + + // function int168Max() pure returns (int256) + int168MaxJump: + INT168_MAX() + + // function oneDays() pure returns (uint256) + oneDaysJump: + ONE_DAYS() + + // function oneMinutes() pure returns (uint256) + oneMinutesJump: + ONE_MINUTES() + + // function int120Min() pure returns (int256) + int120MinJump: + INT120_MIN() + + // function oneSeconds() pure returns (uint256) + oneSecondsJump: + ONE_SECONDS() + + // function int8Max() pure returns (int256) + int8MaxJump: + INT8_MAX() + + // function uint112Max() pure returns (uint256) + uint112MaxJump: + UINT112_MAX() + + // function int8Min() pure returns (int256) + int8MinJump: + INT8_MIN() + + // function oneEther() pure returns (uint256) + oneEtherJump: + ONE_ETHER() + + // function int72Max() pure returns (int256) + int72MaxJump: + INT72_MAX() + + // function int240Max() pure returns (int256) + int240MaxJump: + INT240_MAX() + + // function multiWeeks(uint256) pure returns (uint256) + multiWeeksJump: + MULTI_WEEKS() + + // function int32Min() pure returns (int256) + int32MinJump: + INT32_MIN() + + // function int80Max() pure returns (int256) + int80MaxJump: + INT80_MAX() + + // function int160Min() pure returns (int256) + int160MinJump: + INT160_MIN() + + // function uint256Max() pure returns (uint256) + uint256MaxJump: + UINT256_MAX() + + // function uint240Max() pure returns (uint256) + uint240MaxJump: + UINT240_MAX() + + // function uint192Max() pure returns (uint256) + uint192MaxJump: + UINT192_MAX() + + // function int112Max() pure returns (int256) + int112MaxJump: + INT112_MAX() + + // function uint56Max() pure returns (uint256) + uint56MaxJump: + UINT56_MAX() + + // function int256Min() pure returns (int256) + int256MinJump: + INT256_MIN() + + // function int48Max() pure returns (int256) + int48MaxJump: + INT48_MAX() + + // function int224Max() pure returns (int256) + int224MaxJump: + INT224_MAX() + + // function int128Max() pure returns (int256) + int128MaxJump: + INT128_MAX() + + // function int152Max() pure returns (int256) + int152MaxJump: + INT152_MAX() + + // function int240Min() pure returns (int256) + int240MinJump: + INT240_MIN() + + // function uint232Max() pure returns (uint256) + uint232MaxJump: + UINT232_MAX() + + // function int104Max() pure returns (int256) + int104MaxJump: + INT104_MAX() + + // function uint88Max() pure returns (uint256) + uint88MaxJump: + UINT88_MAX() + + // function int152Min() pure returns (int256) + int152MinJump: + INT152_MIN() +} + +/// @title Constants +/// @notice SPDX-License-Identifier: MIT +/// @author AmadiMichael +/// @notice common constants found in solidity and helpers in huff + + +// value constants +#define constant __ONE_WEI = 0x01 +#define constant __ONE_GWEI = 0x3b9aca00 +#define constant __ONE_ETHER = 0xde0b6b3a7640000 + + +// time constants +#define constant __ONE_SECONDS = 0x01 +#define constant __ONE_MINUTES = 0x3c +#define constant __ONE_HOURS = 0xe10 +#define constant __ONE_DAYS = 0x15180 +#define constant __ONE_WEEKS = 0x93a80 + + +// type ranges constants +#define constant __UINT256_MAX = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +#define constant __UINT248_MAX = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +#define constant __UINT240_MAX = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +#define constant __UINT232_MAX = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +#define constant __UINT224_MAX = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffff +#define constant __UINT216_MAX = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffff +#define constant __UINT208_MAX = 0xffffffffffffffffffffffffffffffffffffffffffffffffffff +#define constant __UINT200_MAX = 0xffffffffffffffffffffffffffffffffffffffffffffffffff +#define constant __UINT192_MAX = 0xffffffffffffffffffffffffffffffffffffffffffffffff +#define constant __UINT184_MAX = 0xffffffffffffffffffffffffffffffffffffffffffffff +#define constant __UINT176_MAX = 0xffffffffffffffffffffffffffffffffffffffffffff +#define constant __UINT168_MAX = 0xffffffffffffffffffffffffffffffffffffffffff +#define constant __UINT160_MAX = 0xffffffffffffffffffffffffffffffffffffffff +#define constant __UINT152_MAX = 0xffffffffffffffffffffffffffffffffffffff +#define constant __UINT144_MAX = 0xffffffffffffffffffffffffffffffffffff +#define constant __UINT136_MAX = 0xffffffffffffffffffffffffffffffffff +#define constant __UINT128_MAX = 0xffffffffffffffffffffffffffffffff +#define constant __UINT120_MAX = 0xffffffffffffffffffffffffffffff +#define constant __UINT112_MAX = 0xffffffffffffffffffffffffffff +#define constant __UINT104_MAX = 0xffffffffffffffffffffffffff +#define constant __UINT96_MAX = 0xffffffffffffffffffffffff +#define constant __UINT88_MAX = 0xffffffffffffffffffffff +#define constant __UINT80_MAX = 0xffffffffffffffffffff +#define constant __UINT72_MAX = 0xffffffffffffffffff +#define constant __UINT64_MAX = 0xffffffffffffffff +#define constant __UINT56_MAX = 0xffffffffffffff +#define constant __UINT48_MAX = 0xffffffffffff +#define constant __UINT40_MAX = 0xffffffffff +#define constant __UINT32_MAX = 0xffffffff +#define constant __UINT24_MAX = 0xffffff +#define constant __UINT16_MAX = 0xffff +#define constant __UINT8_MAX = 0xff + + +#define constant __INT256_MAX = 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +#define constant __INT248_MAX = 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +#define constant __INT240_MAX = 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +#define constant __INT232_MAX = 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffff +#define constant __INT224_MAX = 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffff +#define constant __INT216_MAX = 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffff +#define constant __INT208_MAX = 0x7fffffffffffffffffffffffffffffffffffffffffffffffffff +#define constant __INT200_MAX = 0x7fffffffffffffffffffffffffffffffffffffffffffffffff +#define constant __INT192_MAX = 0x7fffffffffffffffffffffffffffffffffffffffffffffff +#define constant __INT184_MAX = 0x7fffffffffffffffffffffffffffffffffffffffffffff +#define constant __INT176_MAX = 0x7fffffffffffffffffffffffffffffffffffffffffff +#define constant __INT168_MAX = 0x7fffffffffffffffffffffffffffffffffffffffff +#define constant __INT160_MAX = 0x7fffffffffffffffffffffffffffffffffffffff +#define constant __INT152_MAX = 0x7fffffffffffffffffffffffffffffffffffff +#define constant __INT144_MAX = 0x7fffffffffffffffffffffffffffffffffff +#define constant __INT136_MAX = 0x7fffffffffffffffffffffffffffffffff +#define constant __INT128_MAX = 0x7fffffffffffffffffffffffffffffff +#define constant __INT120_MAX = 0x7fffffffffffffffffffffffffffff +#define constant __INT112_MAX = 0x7fffffffffffffffffffffffffff +#define constant __INT104_MAX = 0x7fffffffffffffffffffffffff +#define constant __INT96_MAX = 0x7fffffffffffffffffffffff +#define constant __INT88_MAX = 0x7fffffffffffffffffffff +#define constant __INT80_MAX = 0x7fffffffffffffffffff +#define constant __INT72_MAX = 0x7fffffffffffffffff +#define constant __INT64_MAX = 0x7fffffffffffffff +#define constant __INT56_MAX = 0x7fffffffffffff +#define constant __INT48_MAX = 0x7fffffffffff +#define constant __INT40_MAX = 0x7fffffffff +#define constant __INT32_MAX = 0x7fffffff +#define constant __INT24_MAX = 0x7fffff +#define constant __INT16_MAX = 0x7fff +#define constant __INT8_MAX = 0x7f + +#define constant __INT256_MIN = 0x8000000000000000000000000000000000000000000000000000000000000000 +#define constant __INT248_MIN = 0xff80000000000000000000000000000000000000000000000000000000000000 +#define constant __INT240_MIN = 0xffff800000000000000000000000000000000000000000000000000000000000 +#define constant __INT232_MIN = 0xffffff8000000000000000000000000000000000000000000000000000000000 +#define constant __INT224_MIN = 0xffffffff80000000000000000000000000000000000000000000000000000000 +#define constant __INT216_MIN = 0xffffffffff800000000000000000000000000000000000000000000000000000 +#define constant __INT208_MIN = 0xffffffffffff8000000000000000000000000000000000000000000000000000 +#define constant __INT200_MIN = 0xffffffffffffff80000000000000000000000000000000000000000000000000 +#define constant __INT192_MIN = 0xffffffffffffffff800000000000000000000000000000000000000000000000 +#define constant __INT184_MIN = 0xffffffffffffffffff8000000000000000000000000000000000000000000000 +#define constant __INT176_MIN = 0xffffffffffffffffffff80000000000000000000000000000000000000000000 +#define constant __INT168_MIN = 0xffffffffffffffffffffff800000000000000000000000000000000000000000 +#define constant __INT160_MIN = 0xffffffffffffffffffffffff8000000000000000000000000000000000000000 +#define constant __INT152_MIN = 0xffffffffffffffffffffffffff80000000000000000000000000000000000000 +#define constant __INT144_MIN = 0xffffffffffffffffffffffffffff800000000000000000000000000000000000 +#define constant __INT136_MIN = 0xffffffffffffffffffffffffffffff8000000000000000000000000000000000 +#define constant __INT128_MIN = 0xffffffffffffffffffffffffffffffff80000000000000000000000000000000 +#define constant __INT120_MIN = 0xffffffffffffffffffffffffffffffffff800000000000000000000000000000 +#define constant __INT112_MIN = 0xffffffffffffffffffffffffffffffffffff8000000000000000000000000000 +#define constant __INT104_MIN = 0xffffffffffffffffffffffffffffffffffffff80000000000000000000000000 +#define constant __INT96_MIN = 0xffffffffffffffffffffffffffffffffffffffff800000000000000000000000 +#define constant __INT88_MIN = 0xffffffffffffffffffffffffffffffffffffffffff8000000000000000000000 +#define constant __INT80_MIN = 0xffffffffffffffffffffffffffffffffffffffffffff80000000000000000000 +#define constant __INT72_MIN = 0xffffffffffffffffffffffffffffffffffffffffffffff800000000000000000 +#define constant __INT64_MIN = 0xffffffffffffffffffffffffffffffffffffffffffffffff8000000000000000 +#define constant __INT56_MIN = 0xffffffffffffffffffffffffffffffffffffffffffffffffff80000000000000 +#define constant __INT48_MIN = 0xffffffffffffffffffffffffffffffffffffffffffffffffffff800000000000 +#define constant __INT40_MIN = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffff8000000000 +#define constant __INT32_MIN = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffff80000000 +#define constant __INT24_MIN = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffff800000 +#define constant __INT16_MIN = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8000 +#define constant __INT8_MIN = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80 + + + +// value helpers +// if you don't mind an extra 8 gas then these helper functions can be "helpful" + + +#define macro __WEI() = takes(1) returns(1) { + // expects at least one item on the stack (amount(x) of wei) + // [x, ...] + [__ONE_WEI] mul // [x_wei, ...] +} + +#define macro __GWEI() = takes(1) returns(1) { + // expects at least one item on the stack (amount(x) of gwei) + // [x, ...] + [__ONE_GWEI] mul // [x_gwei, ...] +} + +#define macro __ETHER() = takes(1) returns(1) { + // expects at least one item on the stack (amount(x) of ether) + // [x, ...] + [__ONE_ETHER] mul // [x_ether, ...] +} + + + + +// time helpers +#define macro __SECONDS() = takes(1) returns(1) { + // expects at least one item on the stack (amount(x) of seconds) + // [x, ...] + [__ONE_SECONDS] mul // [x_seconds, ...] +} + +#define macro __MINUTES() = takes(1) returns(1) { + // expects at least one item on the stack (amount(x) of minutes) + // [x, ...] + [__ONE_MINUTES] mul // [x_minutes, ...] +} + +#define macro __HOURS() = takes(1) returns(1) { + // expects at least one item on the stack (amount(x) of hours) + // [x, ...] + [__ONE_HOURS] mul // [x_hours, ...] +} + +#define macro __DAYS() = takes(1) returns(1) { + // expects at least one item on the stack (amount(x) of days) + // [x, ...] + [__ONE_DAYS] mul // [x_days, ...] +} + +#define macro __WEEKS() = takes(1) returns(1) { + // expects at least one item on the stack (amount(x) of weeks) + // [x, ...] + [__ONE_WEEKS] mul // [x_weeks, ...] +} \ No newline at end of file diff --git a/src/utils/__TEMP__bnvxrcqsckqdaprqvhayryuhporeghmzSafeTransferLib.huff b/src/utils/__TEMP__bnvxrcqsckqdaprqvhayryuhporeghmzSafeTransferLib.huff new file mode 100644 index 00000000..e62c27e4 --- /dev/null +++ b/src/utils/__TEMP__bnvxrcqsckqdaprqvhayryuhporeghmzSafeTransferLib.huff @@ -0,0 +1,202 @@ +#define function safeTransferETH(address, uint256) payable returns () +#define function safeTransferFrom(address, address, address, uint256) nonpayable returns () +#define function safeTransfer(address, address, uint256) nonpayable returns () +#define function safeApprove(address, address, uint256) nonpayable returns () + +#define macro SAFE_TRANSFER_ETH_WRAPPER() = { + 0x24 calldataload // [amount] + 0x04 calldataload // [to, amount] + + SAFE_TRANSFER_ETH() + stop +} + +#define macro SAFE_TRANSFER_FROM_WRAPPER() = { + 0x04 calldataload // [token] + 0x64 calldataload // [amount, token] + 0x44 calldataload // [to, amount, token] + 0x24 calldataload // [from, to, amount, token] + + SAFE_TRANSFER_FROM(0x00) + stop +} + +#define macro SAFE_TRANSFER_WRAPPER() = { + 0x04 calldataload // [token] + 0x44 calldataload // [amount, token] + 0x24 calldataload // [to, amount, token] + + SAFE_TRANSFER(0x00) + stop +} + +#define macro SAFE_APPROVE_WRAPPER() = { + 0x04 calldataload // [token] + 0x44 calldataload // [amount, token] + 0x24 calldataload // [to, amount, token] + + SAFE_APPROVE(0x00) + stop +} + +#define macro MAIN() = { + pc calldataload 0xE0 shr + dup1 __FUNC_SIG(safeTransferETH) eq steth jumpi + dup1 __FUNC_SIG(safeTransferFrom) eq stf jumpi + dup1 __FUNC_SIG(safeTransfer) eq st jumpi + dup1 __FUNC_SIG(safeApprove) eq sa jumpi + + 0x00 dup1 revert + + steth: + SAFE_TRANSFER_ETH_WRAPPER() + stf: + SAFE_TRANSFER_FROM_WRAPPER() + st: + SAFE_TRANSFER_WRAPPER() + sa: + SAFE_APPROVE_WRAPPER() +} + + +/// @title SafeTransferLib +/// @notice SPDX-License-Identifier: MIT +/// @notice Safe ETH and ERC20 transfer library that gracefully handles missing return values. +/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/SafeTransferLib.sol) +/// @author Modified from Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/SafeTransferLib.sol) +/// @author clabby +/// @dev Caution! This library won't check that a token has code, responsibility is delegated to the caller. + +/// CONSIDERATION: +/// We could designate byte scratch space for memory +/// which would spare us runtime operations shifting the dynamic memory pointer +/// +/// Designations: +/// - 128 bytes for SAFE_TRANSFER_FROM +/// - 96 bytes for SAFE_TRANSFER +/// - 96 bytes for SAFE_APPROVE + + +/// @notice Safely transfers an `amount` of eth to the address `to` +#define macro SAFE_TRANSFER_ETH() = takes (2) { + // Input stack: [to, amount] + // Output stack: [] + + 0x00 dup1 dup1 dup1 // [0x00, 0x00, 0x00, 0x00, to, amount] + swap5 swap1 swap4 // [to, amount, 0x00, 0x00, 0x00, 0x00] + gas call // [call_success] + success jumpi // [] + + // `ETHTransferFailed()` error + 0xb12d13eb 0x00 mstore + 0x04 0x1c revert + + success: +} + +/// @notice Safely transfers an `amount` of `token` from an address `from` to the address `to` +#define macro SAFE_TRANSFER_FROM(mem_ptr) = takes (4) { + // Input stack: [from, to, value, token] + // Output stack: [] + + __RIGHTPAD(0x23b872dd) // [transferFrom_selector, from, to, amount, token] + // [mem_ptr, transferFrom_selector, from, to, amount, token] + mstore // [from, to, amount, token] + + 0x04 add // [mem_ptr + 0x04, from, to, amount, token] + mstore // [to, amount, token] + 0x24 add // [mem_ptr + 0x24, to, amount, token] + mstore // [amount, token] + 0x44 add // [mem_ptr + 0x44, amount, token] + mstore // [token] + + 0x64 // [0x64, mem_ptr, token] + dup2 0x00 // [0x00, mem_ptr, 0x64, mem_ptr, token] + 0x20 swap5 // [token, 0x00, mem_ptr, 0x64, mem_ptr, 0x20] + gas call // [success] + + returndatasize // [returndatasize, success] + iszero // [returndatasize == 0, success] + // [offset, returndatasize == 0, success] + mload // [data, returndatasize == 0, success] + 0x01 eq // [data == 0x01, returndatasize == 0, success] + or // [data == 0x01 | returndatasize == 0, success] + + and // [success & (data == 0x01 | returndatasize == 0)] + success jumpi // [] + + 0x7939f424 0x00 mstore + 0x04 0x1c revert + + success: +} + +/// @notice Safely transfers an `amount` to an address `to` for the provided `token` +#define macro SAFE_TRANSFER(mem_ptr) = takes (3) { + // Input stack: [to, amount, token] + // Output stack: [] + + __RIGHTPAD(0xa9059cbb) // [transfer_selector, to, amount, token] + // [mem_ptr, transfer_selector, to, amount, token] + mstore // [to, amount, token] + + 0x04 add // [mem_ptr + 0x04, to, amount, token] + mstore // [amount, token] + 0x24 add // [mem_ptr + 0x24, amount, token] + mstore + + 0x44 // [0x44, mem_ptr, token] + dup2 0x00 // [0x00, mem_ptr, 0x44, mem_ptr, token] + 0x20 swap5 // [token, 0x00, mem_ptr, 0x44, mem_ptr, 0x20] + gas call // [success] + + returndatasize // [returndatasize, success] + iszero // [returndatasize == 0, success] + // [offset, returndatasize == 0, success] + mload // [data, returndatasize == 0, success] + 0x01 eq // [data == 0x01, returndatasize == 0, success] + or // [data == 0x01 | returndatasize == 0, success] + + and // [success & (data == 0x01 | returndatasize == 0)] + success jumpi // [] + + 0x90b8ec18 0x00 mstore + 0x04 0x1c revert + + success: +} + +/// @notice Safely approves an `amount` for an address `to` for the provided `token` +#define macro SAFE_APPROVE(mem_ptr) = takes (3) { + // Input stack: [spender, value, token] + // Output stack: [] + + __RIGHTPAD(0x095ea7b3) // [approve_selector, to, amount, token] + // [mem_ptr, approve_selector, to, amount, token] + mstore // [to, amount, token] + + 0x04 add // [mem_ptr + 0x04, to, amount, token] + mstore // [amount, token] + 0x24 add // [mem_ptr + 0x24, amount, token] + mstore + + 0x44 // [0x44, mem_ptr, token] + dup2 0x00 // [0x00, mem_ptr, 0x44, mem_ptr, token] + 0x20 swap5 // [token, 0x00, mem_ptr, 0x44, mem_ptr, 0x20] + gas call // [success] + + returndatasize // [returndatasize, success] + iszero // [returndatasize == 0, success] + // [offset, returndatasize == 0, success] + mload // [data, returndatasize == 0, success] + 0x01 eq // [data == 0x01, returndatasize == 0, success] + or // [data == 0x01 | returndatasize == 0, success] + + and // [success & (data == 0x01 | returndatasize == 0)] + success jumpi // [] + + 0x3e3f8f73 0x00 mstore + 0x04 0x1c revert + + success: +} diff --git a/src/utils/__TEMP__ctwgjphmybkljahoybtnldrrcpneywglECDSA.huff b/src/utils/__TEMP__ctwgjphmybkljahoybtnldrrcpneywglECDSA.huff new file mode 100644 index 00000000..be184d44 --- /dev/null +++ b/src/utils/__TEMP__ctwgjphmybkljahoybtnldrrcpneywglECDSA.huff @@ -0,0 +1,305 @@ +#define function recoverCd(bytes32, bytes calldata) view returns (address) +#define function recoverShortSig(bytes32, bytes32, bytes32) view returns (address) +#define function recoverVRSSig(bytes32, bytes32, bytes32, bytes32) view returns (address) +#define function toEthSignedMessageHash(bytes32) view returns (bytes32) +#define function toEthSignedMessageHashDyn(bytes) view returns (bytes32) + +#define macro RECOVER_CD_WRAPPER() = { + RECOVER_CD_SIG(0x04, 0x64) // [result] + 0x00 mstore // [] + 0x20 0x00 return +} + +#define macro RECOVER_SHORT_SIG_WRAPPER() = { + 0x04 calldataload // [hash] + 0x24 calldataload // [r, hash] + 0x44 calldataload // [vs, r, hash] + RECOVER_SHORT_SIG() // [result] + 0x00 mstore // [] + 0x20 0x00 return +} + +#define macro RECOVER_VRS_SIG_WRAPPER() = { + 0x64 calldataload // [s] + 0x44 calldataload // [r, s] + 0x24 calldataload // [v, r, s] + 0x04 calldataload // [hash, v, r, s] + RECOVER_VRS_SIG() // [result] + 0x00 mstore // [] + 0x20 0x00 return +} + +#define macro TO_ETH_SIGNED_MSG_HASH_WRAPPER() = { + 0x04 calldataload // [hash] + TO_ETH_SIGNED_MSG_HASH() // [result] + 0x00 mstore // [] + 0x20 0x00 return +} + +#define macro TO_ETH_SIGNED_MSG_HASH_DYN_WRAPPER() = { + 0x24 calldataload // [len(s)] + 0x20 add // [len(s) + 0x20] + 0x24 0x60 calldatacopy // [] + TO_ETH_SIGNED_MSG_HASH_DYN(0x60) // [result] + 0x00 mstore // [] + 0x20 0x00 return +} + +#define macro MAIN() = { + pc calldataload 0xE0 shr + dup1 __FUNC_SIG(recoverCd) eq recover_cd jumpi + dup1 __FUNC_SIG(recoverShortSig) eq recover_short_sig jumpi + dup1 __FUNC_SIG(recoverVRSSig) eq recover_vrs_sig jumpi + dup1 __FUNC_SIG(toEthSignedMessageHash) eq to_eth_signed_msg_hash jumpi + dup1 __FUNC_SIG(toEthSignedMessageHashDyn) eq to_eth_signed_msg_hash_dyn jumpi + + // Revert if no function selectors match + 0x00 dup1 revert + + // Fn dispatch + recover_cd: + RECOVER_CD_WRAPPER() + recover_short_sig: + RECOVER_SHORT_SIG_WRAPPER() + recover_vrs_sig: + RECOVER_VRS_SIG_WRAPPER() + to_eth_signed_msg_hash: + TO_ETH_SIGNED_MSG_HASH_WRAPPER() + to_eth_signed_msg_hash_dyn: + TO_ETH_SIGNED_MSG_HASH_DYN_WRAPPER() +} + + +/// @title ECDSA +/// @notice Gas optimized ECDSA wrapper. +/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/ECDSA.sol) +/// @author Modified from Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/ECDSA.sol) +/// @author Modified from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/cryptography/ECDSA.sol) +/// @author clabby + +//////////////////////////////////////////////////////////////// +// CONSTANTS // +//////////////////////////////////////////////////////////////// + +/// @dev The number which `s` must not exceed in order for the signature to be non-malleable. +#define constant MALLEABILITY_THRESHOLD = 0x7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0 + +/// @dev Ethereum Signed Message header. Used in `TO_ETH_SIGNED_MSG_HASH` +#define constant SIG_HEADER = 0x0000000019457468657265756d205369676e6564204d6573736167653a0a3332 + +/// @dev Ethereum Signed Message header. Used in `TO_ETH_SIGNED_MSG_HASH_DYN` +#define constant SIG_HEADER_DYN = 0x00000000000019457468657265756d205369676e6564204d6573736167653a0a + +//////////////////////////////////////////////////////////////// +// RECOVERY OPERATIONS // +//////////////////////////////////////////////////////////////// + +/// @dev Recovers the signer's address from a message digest `hash`, +/// and the `signature`. +/// +/// This macro does NOT accept EIP-2098 short form signatures. +/// Use `recover(bytes32 hash, bytes32 r, bytes32 vs)` for EIP-2098 +/// short form signatures instead. +/// +/// WARNING! +/// The result will be the zero address upon recovery failure. +/// As such, it is extremely important to ensure that the address which +/// the result is compared against is never zero. +/// @notice The `sig_ptr` param must point to the *offset* of the signature data +/// in calldata. +#define macro RECOVER_CD_SIG(hash_ptr, sig_ptr) = returns (1) { + // Input stack: [] + + calldataload // [hash] + 0x20 sub // [sig_len_ptr, hash] + calldataload // [len(signature), hash] + + // If len(signature) != 65, jump to `zero`. + 0x41 eq iszero // [len(signature) != 0x41, hash] + zero jumpi // [hash] + + // Copy `r` and `s` from the calldata + 0x40 dup2 // [0x40, sig_ptr, 0x40, hash] + calldatacopy // [hash] + + // If `s` is not in lower half order, such that the signature is malleable, + // jump to `zero`. + [MALLEABILITY_THRESHOLD] // [malleability_threshold, hash] + 0x60 mload // [s, malleability_threshold, hash] + gt // [s > MALLEABILITY_THRESHOLD, hash] + zero jumpi // [hash] + + // Store `hash` in scratch space @ 0x00 + 0x00 mstore // [] + // Compute `v` and store it in scratch space @ 0x20 + 0x40 add // [0x40 + sig_ptr] + calldataload // [cd] + 0x00 byte // [v] + 0x20 mstore // [] + + 0x20 0x40 0x80 0x00 0x01 // [0x01, 0x00, 0x80, 0x40, 0x20] + gas staticcall pop // [] + + // Restore the zero slot + 0x00 0x60 mstore // [] + + // `returndatasize` will be `0x20` upon success, and `0x00` otherwise. + returndatasize 0x60 sub // [0x60 - returndatasize] + mload // [result] + end jump // [result] + + zero: + pop 0x00 // [0x00] + end: + + // Return stack: [result] +} + +/// @dev Recovers the signer's address from a message digest `hash`, +/// and the EIP-2098 short form signature defined by `r` and `vs`. +/// +/// This function only accepts EIP-2098 short form signatures. +/// See: https://eips.ethereum.org/EIPS/eip-2098 +/// +/// To be honest, I do not recommend using EIP-2098 signatures +/// for simplicity, performance, and security reasons. Most if not +/// all clients support traditional non EIP-2098 signatures by default. +/// As such, this method is intentionally not fully inlined. +/// It is merely included for completeness. - Vectorized +/// +/// WARNING! +/// The `result` will be the zero address upon recovery failure. +/// As such, it is extremely important to ensure that the address which +/// the `result` is compared against is never zero. +#define macro RECOVER_SHORT_SIG() = takes (3) returns (1) { + // Input stack: [vs, r, hash] + + dup1 0xFF shr 0x1B add // [v, vs, r, hash] + swap1 // [vs, v, r, hash] + 0x01 shl 0x01 shr // [s, v, r, hash] + swap3 // [hash, v, r, s] + RECOVER_VRS_SIG() // [result] + + // Return stack: [result] +} + +/// @dev Recovers the signer's address from a message digest `hash`, +/// and the signature defined by `v`, `r`, `s`. +/// +/// WARNING! +/// The `result` will be the zero address upon recovery failure. +/// As such, it is extremely important to ensure that the address which +/// the `result` is compared against is never zero. +#define macro RECOVER_VRS_SIG() = takes (4) returns (1) { + // Input stack: [hash, v, r, s] + + // If `s` is not in lower half order, such that the signature is malleable, + // jump to `zero`. + [MALLEABILITY_THRESHOLD] // [malleability_threshold, hash, v, r, s] + dup5 gt // [s > malleability_threshold, hash, v, r, s] + zero jumpi // [hash, v, r, s] + + 0x00 mstore // [v, r, s] + 0x20 mstore // [r, s] + 0x40 mstore // [s] + 0x60 mstore // [] + + 0x20 0x40 0x80 0x00 0x01 // [0x01, 0x00, 0x80, 0x40, 0x20] + gas staticcall pop // [] + + // Restore the zero slot + 0x00 0x60 mstore // [] + returndatasize 0x60 sub // [0x60 - returndatasize] + mload // [result] + end jump + + zero: + pop pop pop pop 0x00 // [0x00] + end: + + // Return stack: [result] +} + +/// @dev Returns an Ethereum Signed Message, created from a `hash`. +/// This produces a hash corresponding to the one signed with the +/// [`eth_sign`](https://eth.wiki/json-rpc/API#eth_sign) +/// JSON-RPC method as part of EIP-191. +#define macro TO_ETH_SIGNED_MSG_HASH() = takes (1) returns (1) { + // Input stack: [hash] + + // Store in scratch space for hashing. + 0x20 mstore // [] + [SIG_HEADER] 0x00 mstore // [] + + 0x3c 0x04 sha3 // [result] + + // Return stack: [result] +} +/// @dev Returns an Ethereum Signed Message, created from `s`. +/// This produces a hash corresponding to the one signed with the +/// [`eth_sign`](https://eth.wiki/json-rpc/API#eth_sign) +/// JSON-RPC method as part of EIP-191. +/// +/// @dev The msg *must* be stored at a memory offset >= 0x60. Otherwise, +/// the logic that restores the 128 bytes before the `msg_ptr` will +/// underflow, causing a revert due to excessive memory expansion. +#define macro TO_ETH_SIGNED_MSG_HASH_DYN(msg_ptr) = returns (1) { + // Input stack: [] + + // We need at most 128 bytes for Ethereum signed message header. + // The max length of the ASCII reprenstation of a uint256 is 78 bytes. + // The length of "\x19Ethereum Signed Message:\n" is 26 bytes (i.e. 0x1a). + // The next multiple of 32 above 78 + 26 is 128 (i.e. 0x80). + + // Instead of allocating, we temporarily copy the 128 bytes before the + // start of `msg` data to some variables. + // [msg_ptr] + 0x40 dup2 sub mload // [m2, msg_ptr] + 0x20 dup3 sub mload // [m1, m2, msg_ptr] + 0x60 dup4 sub mload // [m3, m1, m2, msg_ptr] + swap3 // [msg_ptr, m1, m2, m3] + dup1 mload // [len(msg), msg_ptr, m1, m2, m3] + + swap1 0x20 add // [ptr, len(msg), m1, m2, m3] + dup2 dup2 add // [end, ptr, len(msg), m1, m2, m3] + swap1 // [ptr, end, len(msg), m1, m2, m3] + dup3 swap1 // [ptr, temp, end, len(msg), m1, m2, m3] + + loop: + 0x01 swap1 sub // [ptr - 0x01, temp, end, len(msg), m1, m2, m3] + 0x0A dup3 mod // [temp % 0x0A, ptr, temp, end, len(msg), m1, m2, m3] + 0x30 add // [(temp % 0x0A) + 0x30, ptr, temp, end, len(msg), m1, m2, m3] + dup2 mstore8 // [ptr, temp, end, len(msg), m1, m2, m3] + 0x0A dup3 div // [temp / 0x0A, ptr, temp, end, len(msg), m1, m2, m3] + swap2 pop // [ptr, temp, end, len(msg), m1, m2, m3] + + // Continue loop if temp != 0 + dup2 loop jumpi // [ptr, temp, end, len(msg), m1, m2, m3] + + // Copy the header into memory. + [SIG_HEADER_DYN] // [sig_header, ptr, temp, end, len(msg), m1, m2, m3] + 0x20 dup3 sub // [ptr - 0x20, sig_header, ptr, temp, end, len(msg), m1, m2, m3] + mstore // [ptr, temp, end, len(msg), m1, m2, m3] + swap1 pop // [ptr, end, len(msg), m1, m2, m3] + + // Compute the keccak256 hash of the memory. + 0x1A swap1 sub // [ptr - 0x1A, end, len(msg), m1, m2, m3] + dup1 // [ptr - 0x1A, ptr - 0x1A, end, len(msg), m1, m2, m3] + swap2 sub // [end - (ptr - 0x1A), ptr - 0x1A, len(msg), m1, m2, m3] + swap1 // [ptr - 0x1A, end - (ptr - 0x1A), len(msg), m1, m2, m3] + sha3 // [result, len(msg), m1, m2, m3] + + // Restore the previous memory. + // TODO: Can keep msg_ptr on stack here and dup rather than pushing it + // 4 times. + swap4 // [m3, len(msg), m1, m2, result] + 0x60 sub // [sig_ptr - 0x60, m3, len(msg), m1, m2, result] + mstore // [len(msg), m1, m2, result] + mstore // [m1, m2, result] + 0x20 sub // [sig_ptr - 0x20, m1, m2, result] + mstore // [m2, result] + 0x40 sub // [sig_ptr - 0x40, m2, result] + mstore // [result] + + // Return stack: [result] +} diff --git a/src/utils/__TEMP__dabwfcmbyyrjifcrrrqvnmskahrxtfwfPausable.huff b/src/utils/__TEMP__dabwfcmbyyrjifcrrrqvnmskahrxtfwfPausable.huff new file mode 100644 index 00000000..9a967559 --- /dev/null +++ b/src/utils/__TEMP__dabwfcmbyyrjifcrrrqvnmskahrxtfwfPausable.huff @@ -0,0 +1,131 @@ +#define function isPaused() view returns (bool) +#define function pause() nonpayable returns () +#define function unpause() nonpayable returns () + + +#define macro CONSTRUCTOR() = takes (0) returns (0) { + PAUSABLE_CONSTRUCTOR() +} + + +#define macro IS_PAUSED_WRAPPER() = takes (0) returns (0) { + PAUSABLE_IS_PAUSED() +} + +#define macro PAUSE_WRAPPER() = takes (0) returns (0) { + PAUSABLE_PAUSE() +} + +#define macro UNPAUSE_WRAPPER() = takes (0) returns (0) { + PAUSABLE_UNPAUSE() +} + + +#define macro MAIN() = takes (0) returns (0) { + pc calldataload 0xe0 shr // [sig] + + dup1 __FUNC_SIG(pause) eq pause jumpi + dup1 __FUNC_SIG(unpause) eq unpause jumpi + dup1 __FUNC_SIG(isPaused) eq is_paused jumpi + + 0x00 dup1 revert + + pause: + PAUSE_WRAPPER() + unpause: + UNPAUSE_WRAPPER() + is_paused: + IS_PAUSED_WRAPPER() +} + +/// @title Pausable +/// @notice SPDX-License-Identifier: MIT +/// @author zarf.eth +/// @notice A Pausable implementation + + +// Interface + +/// @notice returns whether the contract is paused +#define function isPaused() view returns (bool) + +/// @notice Pauses the contract +/// @dev Only callable when the contract is unpaused. +#define function pause() nonpayable returns () + +/// @notice Unpauses the contract +/// @dev Only callable when the contract is paused. +#define function unpause() nonpayable returns () + +/// @notice Emitted when contract is paused. +#define event Paused(address) + +/// @notice Emitted when contract is unpaused. +#define event Unpaused(address) + + +// Storage + +/// @notice Paused Storage Slot +#define constant PAUSED_SLOT = FREE_STORAGE_POINTER() + +/// @notice Unpaused representation +#define constant NOT_PAUSED = 0x01 + +/// @notice Paused representation +#define constant PAUSED = 0x02 + + +/// @notice Pausable constructor +#define macro PAUSABLE_CONSTRUCTOR() = takes (0) returns (0) { + [NOT_PAUSED] [PAUSED_SLOT] sstore // [] +} + +/// @notice whenNotPaused modifier +#define macro WHEN_NOT_PAUSED_MODIFIER() = takes (0) returns (0) { + [PAUSED_SLOT] sload // [isPaused] + [NOT_PAUSED] eq when_not_paused jumpi // [] + 0x00 dup1 revert // [] + when_not_paused: // [] +} + +/// @notice whenPaused modifier +#define macro WHEN_PAUSED_MODIFIER() = takes (0) returns (0) { + [PAUSED_SLOT] sload // [isPaused] + [PAUSED] eq when_paused jumpi // [] + 0x00 dup1 revert // [] + when_paused: // [] +} + +/// @notice return whether contract is paused +#define macro PAUSABLE_IS_PAUSED() = takes (0) returns (0) { + 0x01 // [1] + [PAUSED_SLOT] sload // [isPaused, 1] + sub // [bool] + 0x00 mstore // [] + 0x20 0x00 return // [] +} + +/// @notice Pause the contract +#define macro PAUSABLE_PAUSE() = takes (0) returns (0) { + WHEN_NOT_PAUSED_MODIFIER() // [] + + //emit Paused(address) + caller __EVENT_HASH(Paused) 0x00 dup1 // [0, 0, EVENT_PAUSED, msg.sender] + log2 // [] + + [PAUSED] [PAUSED_SLOT] sstore // [] + stop +} + +/// @notice Unpause the contract +#define macro PAUSABLE_UNPAUSE() = takes (0) returns (0) { + WHEN_PAUSED_MODIFIER() // [] + + //emit Unpaused(address) + caller __EVENT_HASH(Unpaused) 0x00 dup1 // [0, 0, EVENT_UNPAUSED, msg.sender] + log2 // [] + + [NOT_PAUSED] [PAUSED_SLOT] sstore // [] + stop +} diff --git a/src/utils/__TEMP__dolvqpolutctxhctjzvajsrpbtpqfvdlCalls.huff b/src/utils/__TEMP__dolvqpolutctxhctjzvajsrpbtpqfvdlCalls.huff new file mode 100644 index 00000000..019625c2 --- /dev/null +++ b/src/utils/__TEMP__dolvqpolutctxhctjzvajsrpbtpqfvdlCalls.huff @@ -0,0 +1,217 @@ + +#define function callFunc() payable returns () +#define function staticcallFunc() payable returns () +#define function callcodeFunc() payable returns () + +#define macro CALL_WRAPPER() = takes (0) returns (0) { + // Store 0xba5ed in memory + 0xba5ed dup1 0x00 mstore // [0xba5ed] + + // Static Call + CALL(0x01, 0x00, 0x01, 0x00, 0x00, 0x04, 0xFFFFFFFF) // [success, 0xba5ed] + + // Revert if call is unsuccessful + iszero iszero cont jumpi + 0x00 dup1 revert + cont: + + // Load the result + 0x00 mload // [res, 0xba5ed] + + // Compare the results and revert if unequal + eq success jumpi // [] + 0x00 dup1 revert + success: + + stop +} + +#define macro STATICCALL_WRAPPER() = takes (0) returns (0) { + // Store 0xba5ed in memory + 0xba5ed dup1 0x00 mstore // [0xba5ed] + + // Static Call + STATICCALL(0x01, 0x00, 0x01, 0x00, 0x04, 0xFFFFFFFF) // [success, 0xba5ed] + + // Revert if call is unsuccessful + iszero iszero cont jumpi + 0x00 dup1 revert + cont: + + // Load the result + 0x00 mload // [res, 0xba5ed] + + // Compare the results and revert if unequal + eq success jumpi // [] + 0x00 dup1 revert + success: + + stop +} + +#define macro CALLCODE_WRAPPER() = takes (0) returns (0) { + // TODO + + stop +} + +#define macro MAIN() = takes (0) returns (0) { + // Load the function selector + pc calldataload 0xE0 shr // [sig] + + // Match on the function selector + dup1 __FUNC_SIG(callFunc) eq call_jump jumpi // [sig] + dup1 __FUNC_SIG(staticcallFunc) eq staticcall_jump jumpi // [sig] + dup1 __FUNC_SIG(callcodeFunc) eq callcode_jump jumpi // [sig] + + 0x00 dup1 revert + + call_jump: + CALL_WRAPPER() + staticcall_jump: + STATICCALL_WRAPPER() + callcode_jump: + CALLCODE_WRAPPER() +} + + +/// @title Calls +/// @notice SPDX-License-Identifier: MIT +/// @author asnared +/// @author Franfran +/// @notice Calls is a library of utility functions for calling contracts + +/// @notice Calls a contract with the given arguments +/// @notice Returns the success of the call +/// @notice Returndata is left in memory for the caller to handle +/// @param ret_size The size of the return data +/// @param ret_offset The offset in memory to store the return data +/// @param arg_size The size of the arguments +/// @param arg_offset The offset in memory of the arguments +/// @param value The value to send with the call +/// @param to The address to call +/// @param gas The amount of gas to send with the call +#define macro CALL( + ret_size, + ret_offset, + arg_size, + arg_offset, + value, + to, + maxgas +) = takes (0) returns (1) { + // [retSize] + // [retOffset, retSize] + // [argSize, retOffset, retSize] + // [argOffset, argSize, retOffset, retSize] + // [value, argOffset, argSize, retOffset, retSize] + // [to, value, argOffset, argSize, retOffset, retSize] + // [gas, to, value, argOffset, argSize, retOffset, retSize] + call // [success] +} + +/// @notice Staticalls a contract with the given arguments +/// @notice Returns the success of the call +/// @notice Returndata is left in memory for the caller to handle +/// @dev This instructions is equivalent to CALL, except that it does not allow any state modifying instructions or sending ETH in the sub context. +/// @dev The disallowed instructions are CREATE, CREATE2, LOG0, LOG1, LOG2, LOG3, LOG4, SSTORE, SELFDESTRUCT and CALL if the value sent is not 0. +/// @dev If the size of the return data is not known, it can also be retrieved after the call with the instructions RETURNDATASIZE and RETURNDATACOPY (since the Byzantium fork). +/// @param ret_size The size of the return data +/// @param ret_offset The offset in memory to store the return data +/// @param arg_size The size of the arguments +/// @param arg_offset The offset in memory of the arguments +/// @param to The address to call +/// @param gas The amount of gas to send with the call +#define macro STATICCALL( + ret_size, + ret_offset, + arg_size, + arg_offset, + to, + maxgas +) = takes (0) returns (1) { + // [retSize] + // [retOffset, retSize] + // [argSize, retOffset, retSize] + // [argOffset, argSize, retOffset, retSize] + // [to, argOffset, argSize, retOffset, retSize] + // [gas, to, argOffset, argSize, retOffset, retSize] + staticcall // [success] +} + +/// @notice Codecalls a contract with the given arguments +/// @notice Returns the success of the call +/// @notice Returndata is left in memory for the caller to handle +/// @dev Creates a new sub context as if calling itself, but with the code of the given account. +/// @dev In particular the storage remains the same. Note that an account with no code will return success as true. +/// @dev If the size of the return data is not known, it can also be retrieved after the call with the instructions RETURNDATASIZE and RETURNDATACOPY (since the Byzantium fork). +/// @param ret_size The size of the return data +/// @param ret_offset The offset in memory to store the return data +/// @param arg_size The size of the arguments +/// @param arg_offset The offset in memory of the arguments +/// @param value The value to send with the call +/// @param to The address to call +/// @param gas The amount of gas to send with the call +#define macro CALLCODE( + ret_size, + ret_offset, + arg_size, + arg_offset, + value, + to, + maxgas +) = takes (0) returns (1) { + // [retSize] + // [retOffset, retSize] + // [argSize, retOffset, retSize] + // [argOffset, argSize, retOffset, retSize] + // [value, argOffset, argSize, retOffset, retSize] + // [to, argOffset, argSize, retOffset, retSize] + // [gas, to, argOffset, argSize, retOffset, retSize] + callcode // [success] +} + +/// @notice Test call the identity precompile +#define test TEST_CALL() = takes (0) returns (0) { + // Store 0xba5ed in memory + 0xba5ed dup1 0x00 mstore // [0xba5ed] + + // Static Call + CALL(0x01, 0x00, 0x01, 0x00, 0x00, 0x04, 0xFFFFFFFF) // [success, 0xba5ed] + + // Revert if call is unsuccessful + iszero iszero cont jumpi + 0x00 dup1 revert + cont: + + // Load the result + 0x00 mload // [res, 0xba5ed] + + // Compare the results and revert if unequal + eq success jumpi // [] + 0x00 dup1 revert + success: +} + +/// @notice Test staticcall the identity precompile +#define test TEST_STATIC_CALL() = takes (0) returns (0) { + // Store 0xba5ed in memory + 0xba5ed dup1 0x00 mstore // [0xba5ed] + + // Static Call + STATICCALL(0x01, 0x00, 0x01, 0x00, 0x04, 0xFFFFFFFF) // [success, 0xba5ed] + + // Revert if call is unsuccessful + iszero iszero cont jumpi + 0x00 dup1 revert + cont: + + // Load the result + 0x00 mload // [res, 0xba5ed] + + // Compare the results and revert if unequal + eq success jumpi // [] + 0x00 dup1 revert + success: +} + diff --git a/src/utils/__TEMP__ejbyrnbkhzztmedggubevwdmphskibtxMerkleDistributor.huff b/src/utils/__TEMP__ejbyrnbkhzztmedggubevwdmphskibtxMerkleDistributor.huff new file mode 100644 index 00000000..867e8160 --- /dev/null +++ b/src/utils/__TEMP__ejbyrnbkhzztmedggubevwdmphskibtxMerkleDistributor.huff @@ -0,0 +1,247 @@ + +#define macro CONSTRUCTOR() = takes (0) returns (0) { + MERKLE_DISTRIBUTOR_CONSTRUCTOR() +} + +#define macro MAIN() = takes (0) returns (0) { + pc calldataload 0xE0 shr + MERKLE_DISTRIBUTOR_MAIN() + 0x00 dup1 revert +} + + +/// @title Merkle Distributor +/// @notice SPDX-License-Identifier: MIT +/// @author Ben Leimberger +/// @author Magna +/// @author asnared +/// @notice Minimal, gas efficient Merkle Distributor implementation + + +// Imports +#include "./CommonErrors.huff" +#include "./MerkleProofLib.huff" +#include "./Address.huff" +#include "./ERC20Transfer.huff" + +// Interface +#define function claim(uint256,address,uint256,bytes32[]) nonpayable returns () + +#define function getMerkleRoot() view returns (bytes32) +#define function getTokenAddress() view returns (address) +#define function isClaimed(uint256) view returns (bool) + +// Storage Slots +#define constant CLAIMED_BIT_MAP_SLOT = FREE_STORAGE_POINTER() // 0x00 +#define constant TOKEN_ADDR_SLOT = FREE_STORAGE_POINTER() // 0x01 +#define constant MERKLE_ROOT_SLOT = FREE_STORAGE_POINTER() // 0x02 + +// Errors +#define error TransferError(string) +#define error ClaimedError(string) +#define error ProofError(string) + + +/// @notice Get Merkle Root +/// @notice Entry point for: getMerkleRoot() +/// @dev Fetches merkle root from storage slot +/// @param {calldata} [] +/// @return {return} [bytes32 root] +#define macro GET_MERKLE_ROOT() = takes (0) returns (0) { + // Load value from storage + [MERKLE_ROOT_SLOT] sload // [merkle_root] + + // Store value in memory + 0x00 mstore // [] + + // Return value + 0x20 0x00 return // [] +} + +/// @notice Get Token Address +#define macro GET_TOKEN_ADDR() = takes (0) returns (0) { + // Load value from storage + [TOKEN_ADDR_SLOT] sload // [token_addr] + + // Store value in memory + 0x00 mstore // [] + + // Return value + 0x20 0x00 return // [] +} + + +/// Is Claimed +/// @notice Entry point for: isClaimed(uint256) +/// @dev Check if index is claimed +/// @param {calldata} [uint256 index] +/// @return {return} [bytes32 root] +#define macro IS_CLAIMED() = takes (0) returns (0) { + // Load first argument from calldata + 0x04 calldataload // [index] + + // Utility macro + __UTIL_IS_CLAIMED() // [isEqual] + + // store result in memory + 0x00 mstore // [] + 0x20 0x00 return +} + +/// @dev stores result in 0x00 to 0x20 memory slot +#define macro __UTIL_IS_CLAIMED() = takes (1) returns (1) { + // Stack input: // [arg0] + // Stack output: // [isEqual] + // index / 256 + 0x100 dup2 div // [index] + + __UTIL_GENERATE_MAPPING_KEY() // [key(claimed[index]), arg0] + + // Load mapping key + sload // [claimed[index], arg0] + + // index % 256 [claimed[index], arg0] + 0x1 0x100 dup4 mod shl // [mask, claimed[index], arg0] + dup1 swap2 dup2 and // [masked, mask, claimed[index], arg0] + eq // [isEqual, claimed[index], arg0] + swap2 pop pop // [isEqual] +} + + +/// @notice Set as claimed +#define macro __UTIL_SET_CLAIMED() = takes (1) returns (0) { + // Stack input: // [arg0] + + // index / 256 + 0x100 dup2 div // [index, arg0] + + __UTIL_GENERATE_MAPPING_KEY() // [key(claimed[index]), arg0] + + // Load mapping key + dup1 sload // [claimed[index], key(claimed[index]), arg0] + + // index % 256 [claimed[index], key(claimed[index]), arg0] + 0x1 0x100 dup5 mod shl // [mask, claimed[index], key(claimed[index]), arg0] + or // [masked, key(claimed[to]), arg0] + + // Update + swap1 sstore pop // [] +} + +/// @notice Creates a mapping key from an index +#define macro __UTIL_GENERATE_MAPPING_KEY() = takes (1) returns (1) { + // Stack input: [index] + // Stack output: [key(claimed[index])] + 0x00 mstore // [] + [CLAIMED_BIT_MAP_SLOT] 0x20 mstore // [] + + // key(claimed[index]) = keccak256(index . claimedBitMapSlot) + 0x40 0x00 sha3 // [key(claimed[index])] +} + +/// @notice Claim +/// @notice Entry point for: claim(uint256,address,uint256,bytes[]) +/// @dev Claim distribution with proof +/// @param {calldata} [uint256 index, address account, uint256 amount, bytes[] proof] +/// @return {return} [] +#define macro CLAIM() = takes (0) returns (0) { + // Preload merkle root + [MERKLE_ROOT_SLOT] sload // [root] + + // Load arguments from calldata + 0x44 calldataload // [amount, root] + 0x24 calldataload MASK_ADDRESS() // [account, amount, root] + 0x04 calldataload // [index, account, amount, root] + + // Check if an index is claimed + dup1 __UTIL_IS_CLAIMED() // [isClaimed, index, account, amount, root] + iszero cont jumpi // [index, account, amount, root] + ALREADY_CLAIMED(0x00) + cont: + + // EncodePacked + // [ 32 bytes | 20 bytes | 32 bytes ] = 84 bytes + 0x00 mstore // [account, amount, root] + 0x60 shl // [account << 12, amount, root] + 0x20 mstore // [amount, root] + 0x34 mstore // [root] + 0x54 0x00 sha3 // [leaf, root] + + // Verify merkle proof + 0x64 calldataload 0x4 add // [&proof_length, leaf, root] + + // Required() + VERIFY_PROOF() // [isProven] + verified jumpi // [] + INVALID_PROOF(0x00) + verified: + + // Mark it claimed + 0x04 calldataload // [arg0] + __UTIL_SET_CLAIMED() // [] + + // Load other calldata arguments + [TOKEN_ADDR_SLOT] sload // [getter_addr] + 0x44 calldataload // [amount, getter_addr] + 0x24 calldataload // [address_raw, amount, getter_addr] + MASK_ADDRESS() // [address, amount, getter_addr] + + // Send the token + ERC20_TRANSFER() + + // Finish Execution + stop +} + +/// @notice Constructor +/// @param address The address of the token to distribute +/// @param merkleRoot The merkle root of the merkle tree +#define macro MERKLE_DISTRIBUTOR_CONSTRUCTOR() = takes (0) returns (0) { + // Copy the first argument into memory + 0x20 // [size] - byte size to copy + 0x40 codesize sub // [offset, size] - offset in the code to copy from + 0x00 // [mem, offset, size] - offset in memory to copy to + codecopy // [] + + // Store the first argument in storage + 0x00 mload // [arg1] + [TOKEN_ADDR_SLOT] // [TOKEN_ADDR, arg1] + sstore // [] + + // Copy the second argument into memory + 0x20 // [size] - byte size to copy + 0x20 codesize sub // [offset, size] - offset in the code to copy from + 0x00 // [mem, offset, size] - offset in memory to copy to + codecopy // [] + + // Store the second argument in storage + 0x00 mload // [arg2] + [MERKLE_ROOT_SLOT] // [CONSTRUCTOR_ARG_TWO, arg2] + sstore // [] +} + +/// @notice Function Dispatch +/// @notice Takes the first 4 bytes of calldata (aka the function selector) and dispatches to the appropriate function +/// @notice If non match, execution proceeds as the code is inlined +#define macro MERKLE_DISTRIBUTOR_MAIN() = takes (1) returns (1) { + // Input Stack: [function_selector] + + dup1 __FUNC_SIG(getTokenAddress) eq getTokenAddress jumpi + dup1 __FUNC_SIG(getMerkleRoot) eq getMerkleRoot jumpi + dup1 __FUNC_SIG(isClaimed) eq isClaimed jumpi + dup1 __FUNC_SIG(claim) eq claim jumpi + + // Jump to the end if non match + no_match jump + + getMerkleRoot: + GET_MERKLE_ROOT() + getTokenAddress: + GET_TOKEN_ADDR() + isClaimed: + IS_CLAIMED() + claim: + CLAIM() + + no_match: +} \ No newline at end of file diff --git a/src/utils/__TEMP__epqcrijckuxiernloalienlasrtffackConstants.huff b/src/utils/__TEMP__epqcrijckuxiernloalienlasrtffackConstants.huff new file mode 100644 index 00000000..157180e7 --- /dev/null +++ b/src/utils/__TEMP__epqcrijckuxiernloalienlasrtffackConstants.huff @@ -0,0 +1,1789 @@ + +// interface +#define function oneWei() pure returns(uint256) +#define function oneGwei() pure returns(uint256) +#define function oneEther() pure returns(uint256) +#define function oneSeconds() pure returns(uint256) +#define function oneMinutes() pure returns(uint256) +#define function oneHours() pure returns(uint256) +#define function oneDays() pure returns(uint256) +#define function oneWeeks() pure returns(uint256) + +#define function uint256Max() pure returns(uint256) +#define function uint248Max() pure returns(uint256) +#define function uint240Max() pure returns(uint256) +#define function uint232Max() pure returns(uint256) +#define function uint224Max() pure returns(uint256) +#define function uint216Max() pure returns(uint256) +#define function uint208Max() pure returns(uint256) +#define function uint200Max() pure returns(uint256) +#define function uint192Max() pure returns(uint256) +#define function uint184Max() pure returns(uint256) +#define function uint176Max() pure returns(uint256) +#define function uint168Max() pure returns(uint256) +#define function uint160Max() pure returns(uint256) +#define function uint152Max() pure returns(uint256) +#define function uint144Max() pure returns(uint256) +#define function uint136Max() pure returns(uint256) +#define function uint128Max() pure returns(uint256) +#define function uint120Max() pure returns(uint256) +#define function uint112Max() pure returns(uint256) +#define function uint104Max() pure returns(uint256) +#define function uint96Max() pure returns(uint256) +#define function uint88Max() pure returns(uint256) +#define function uint80Max() pure returns(uint256) +#define function uint72Max() pure returns(uint256) +#define function uint64Max() pure returns(uint256) +#define function uint56Max() pure returns(uint256) +#define function uint48Max() pure returns(uint256) +#define function uint40Max() pure returns(uint256) +#define function uint32Max() pure returns(uint256) +#define function uint24Max() pure returns(uint256) +#define function uint16Max() pure returns(uint256) +#define function uint8Max() pure returns(uint256) + +#define function int256Max() pure returns(int256) +#define function int248Max() pure returns(int256) +#define function int240Max() pure returns(int256) +#define function int232Max() pure returns(int256) +#define function int224Max() pure returns(int256) +#define function int216Max() pure returns(int256) +#define function int208Max() pure returns(int256) +#define function int200Max() pure returns(int256) +#define function int192Max() pure returns(int256) +#define function int184Max() pure returns(int256) +#define function int176Max() pure returns(int256) +#define function int168Max() pure returns(int256) +#define function int160Max() pure returns(int256) +#define function int152Max() pure returns(int256) +#define function int144Max() pure returns(int256) +#define function int136Max() pure returns(int256) +#define function int128Max() pure returns(int256) +#define function int120Max() pure returns(int256) +#define function int112Max() pure returns(int256) +#define function int104Max() pure returns(int256) +#define function int96Max() pure returns(int256) +#define function int88Max() pure returns(int256) +#define function int80Max() pure returns(int256) +#define function int72Max() pure returns(int256) +#define function int64Max() pure returns(int256) +#define function int56Max() pure returns(int256) +#define function int48Max() pure returns(int256) +#define function int40Max() pure returns(int256) +#define function int32Max() pure returns(int256) +#define function int24Max() pure returns(int256) +#define function int16Max() pure returns(int256) +#define function int8Max() pure returns(int256) + +#define function int256Min() pure returns(int256) +#define function int248Min() pure returns(int256) +#define function int240Min() pure returns(int256) +#define function int232Min() pure returns(int256) +#define function int224Min() pure returns(int256) +#define function int216Min() pure returns(int256) +#define function int208Min() pure returns(int256) +#define function int200Min() pure returns(int256) +#define function int192Min() pure returns(int256) +#define function int184Min() pure returns(int256) +#define function int176Min() pure returns(int256) +#define function int168Min() pure returns(int256) +#define function int160Min() pure returns(int256) +#define function int152Min() pure returns(int256) +#define function int144Min() pure returns(int256) +#define function int136Min() pure returns(int256) +#define function int128Min() pure returns(int256) +#define function int120Min() pure returns(int256) +#define function int112Min() pure returns(int256) +#define function int104Min() pure returns(int256) +#define function int96Min() pure returns(int256) +#define function int88Min() pure returns(int256) +#define function int80Min() pure returns(int256) +#define function int72Min() pure returns(int256) +#define function int64Min() pure returns(int256) +#define function int56Min() pure returns(int256) +#define function int48Min() pure returns(int256) +#define function int40Min() pure returns(int256) +#define function int32Min() pure returns(int256) +#define function int24Min() pure returns(int256) +#define function int16Min() pure returns(int256) +#define function int8Min() pure returns(int256) + +#define function multiWei(uint256) pure returns(uint256) +#define function multiGwei(uint256) pure returns(uint256) +#define function multiEther(uint256) pure returns(uint256) +#define function multiSeconds(uint256) pure returns(uint256) +#define function multiMinutes(uint256) pure returns(uint256) +#define function multiHours(uint256) pure returns(uint256) +#define function multiDays(uint256) pure returns(uint256) +#define function multiWeeks(uint256) pure returns(uint256) + + +#define macro ONE_WEI() = takes(0) returns(0) { + [__ONE_WEI] 0x00 mstore + 0x20 0x00 return +} + +#define macro ONE_GWEI() = takes(0) returns(0) { + [__ONE_GWEI] 0x00 mstore + 0x20 0x00 return +} + +#define macro ONE_ETHER() = takes(0) returns(0) { + [__ONE_ETHER] 0x00 mstore + 0x20 0x00 return +} + +#define macro ONE_SECONDS() = takes(0) returns(0) { + [__ONE_SECONDS] 0x00 mstore + 0x20 0x00 return +} + +#define macro ONE_MINUTES() = takes(0) returns(0) { + [__ONE_MINUTES] 0x00 mstore + 0x20 0x00 return +} + +#define macro ONE_HOURS() = takes(0) returns(0) { + [__ONE_HOURS] 0x00 mstore + 0x20 0x00 return +} + +#define macro ONE_DAYS() = takes(0) returns(0) { + [__ONE_DAYS] 0x00 mstore + 0x20 0x00 return +} + +#define macro ONE_WEEKS() = takes(0) returns(0) { + [__ONE_WEEKS] 0x00 mstore + 0x20 0x00 return +} + + + +#define macro UINT256_MAX() = takes(0) returns(0) { + [__UINT256_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro UINT248_MAX() = takes(0) returns(0) { + [__UINT248_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro UINT240_MAX() = takes(0) returns(0) { + [__UINT240_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro UINT232_MAX() = takes(0) returns(0) { + [__UINT232_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro UINT224_MAX() = takes(0) returns(0) { + [__UINT224_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro UINT216_MAX() = takes(0) returns(0) { + [__UINT216_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro UINT208_MAX() = takes(0) returns(0) { + [__UINT208_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro UINT200_MAX() = takes(0) returns(0) { + [__UINT200_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro UINT192_MAX() = takes(0) returns(0) { + [__UINT192_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro UINT184_MAX() = takes(0) returns(0) { + [__UINT184_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro UINT176_MAX() = takes(0) returns(0) { + [__UINT176_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro UINT168_MAX() = takes(0) returns(0) { + [__UINT168_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro UINT160_MAX() = takes(0) returns(0) { + [__UINT160_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro UINT152_MAX() = takes(0) returns(0) { + [__UINT152_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro UINT144_MAX() = takes(0) returns(0) { + [__UINT144_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro UINT136_MAX() = takes(0) returns(0) { + [__UINT136_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro UINT128_MAX() = takes(0) returns(0) { + [__UINT128_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro UINT120_MAX() = takes(0) returns(0) { + [__UINT120_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro UINT112_MAX() = takes(0) returns(0) { + [__UINT112_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro UINT104_MAX() = takes(0) returns(0) { + [__UINT104_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro UINT96_MAX() = takes(0) returns(0) { + [__UINT96_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro UINT88_MAX() = takes(0) returns(0) { + [__UINT88_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro UINT80_MAX() = takes(0) returns(0) { + [__UINT80_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro UINT72_MAX() = takes(0) returns(0) { + [__UINT72_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro UINT64_MAX() = takes(0) returns(0) { + [__UINT64_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro UINT56_MAX() = takes(0) returns(0) { + [__UINT56_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro UINT48_MAX() = takes(0) returns(0) { + [__UINT48_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro UINT40_MAX() = takes(0) returns(0) { + [__UINT40_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro UINT32_MAX() = takes(0) returns(0) { + [__UINT32_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro UINT24_MAX() = takes(0) returns(0) { + [__UINT24_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro UINT16_MAX() = takes(0) returns(0) { + [__UINT16_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro UINT8_MAX() = takes(0) returns(0) { + [__UINT8_MAX] 0x00 mstore + 0x20 0x00 return +} + + + + + + +#define macro INT256_MAX() = takes(0) returns(0) { + [__INT256_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT248_MAX() = takes(0) returns(0) { + [__INT248_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT240_MAX() = takes(0) returns(0) { + [__INT240_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT232_MAX() = takes(0) returns(0) { + [__INT232_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT224_MAX() = takes(0) returns(0) { + [__INT224_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT216_MAX() = takes(0) returns(0) { + [__INT216_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT208_MAX() = takes(0) returns(0) { + [__INT208_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT200_MAX() = takes(0) returns(0) { + [__INT200_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT192_MAX() = takes(0) returns(0) { + [__INT192_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT184_MAX() = takes(0) returns(0) { + [__INT184_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT176_MAX() = takes(0) returns(0) { + [__INT176_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT168_MAX() = takes(0) returns(0) { + [__INT168_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT160_MAX() = takes(0) returns(0) { + [__INT160_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT152_MAX() = takes(0) returns(0) { + [__INT152_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT144_MAX() = takes(0) returns(0) { + [__INT144_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT136_MAX() = takes(0) returns(0) { + [__INT136_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT128_MAX() = takes(0) returns(0) { + [__INT128_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT120_MAX() = takes(0) returns(0) { + [__INT120_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT112_MAX() = takes(0) returns(0) { + [__INT112_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT104_MAX() = takes(0) returns(0) { + [__INT104_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT96_MAX() = takes(0) returns(0) { + [__INT96_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT88_MAX() = takes(0) returns(0) { + [__INT88_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT80_MAX() = takes(0) returns(0) { + [__INT80_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT72_MAX() = takes(0) returns(0) { + [__INT72_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT64_MAX() = takes(0) returns(0) { + [__INT64_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT56_MAX() = takes(0) returns(0) { + [__INT56_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT48_MAX() = takes(0) returns(0) { + [__INT48_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT40_MAX() = takes(0) returns(0) { + [__INT40_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT32_MAX() = takes(0) returns(0) { + [__INT32_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT24_MAX() = takes(0) returns(0) { + [__INT24_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT16_MAX() = takes(0) returns(0) { + [__INT16_MAX] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT8_MAX() = takes(0) returns(0) { + [__INT8_MAX] 0x00 mstore + 0x20 0x00 return +} + + + + + + +#define macro INT256_MIN() = takes(0) returns(0) { + [__INT256_MIN] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT248_MIN() = takes(0) returns(0) { + [__INT248_MIN] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT240_MIN() = takes(0) returns(0) { + [__INT240_MIN] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT232_MIN() = takes(0) returns(0) { + [__INT232_MIN] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT224_MIN() = takes(0) returns(0) { + [__INT224_MIN] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT216_MIN() = takes(0) returns(0) { + [__INT216_MIN] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT208_MIN() = takes(0) returns(0) { + [__INT208_MIN] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT200_MIN() = takes(0) returns(0) { + [__INT200_MIN] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT192_MIN() = takes(0) returns(0) { + [__INT192_MIN] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT184_MIN() = takes(0) returns(0) { + [__INT184_MIN] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT176_MIN() = takes(0) returns(0) { + [__INT176_MIN] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT168_MIN() = takes(0) returns(0) { + [__INT168_MIN] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT160_MIN() = takes(0) returns(0) { + [__INT160_MIN] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT152_MIN() = takes(0) returns(0) { + [__INT152_MIN] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT144_MIN() = takes(0) returns(0) { + [__INT144_MIN] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT136_MIN() = takes(0) returns(0) { + [__INT136_MIN] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT128_MIN() = takes(0) returns(0) { + [__INT128_MIN] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT120_MIN() = takes(0) returns(0) { + [__INT120_MIN] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT112_MIN() = takes(0) returns(0) { + [__INT112_MIN] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT104_MIN() = takes(0) returns(0) { + [__INT104_MIN] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT96_MIN() = takes(0) returns(0) { + [__INT96_MIN] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT88_MIN() = takes(0) returns(0) { + [__INT88_MIN] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT80_MIN() = takes(0) returns(0) { + [__INT80_MIN] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT72_MIN() = takes(0) returns(0) { + [__INT72_MIN] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT64_MIN() = takes(0) returns(0) { + [__INT64_MIN] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT56_MIN() = takes(0) returns(0) { + [__INT56_MIN] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT48_MIN() = takes(0) returns(0) { + [__INT48_MIN] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT40_MIN() = takes(0) returns(0) { + [__INT40_MIN] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT32_MIN() = takes(0) returns(0) { + [__INT32_MIN] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT24_MIN() = takes(0) returns(0) { + [__INT24_MIN] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT16_MIN() = takes(0) returns(0) { + [__INT16_MIN] 0x00 mstore + 0x20 0x00 return +} + +#define macro INT8_MIN() = takes(0) returns(0) { + [__INT8_MIN] 0x00 mstore + 0x20 0x00 return +} + + + + +#define macro MULTI_WEI() = takes(0) returns(0) { + 0x04 calldataload __WEI() 0x00 mstore + 0x20 0x00 return +} + +#define macro MULTI_GWEI() = takes(0) returns(0) { + 0x04 calldataload __GWEI() 0x00 mstore + 0x20 0x00 return +} + +#define macro MULTI_ETHER() = takes(0) returns(0) { + 0x04 calldataload __ETHER() 0x00 mstore + 0x20 0x00 return +} + +#define macro MULTI_SECONDS() = takes(0) returns(0) { + 0x04 calldataload __SECONDS() 0x00 mstore + 0x20 0x00 return +} + +#define macro MULTI_MINUTES() = takes(0) returns(0) { + 0x04 calldataload __MINUTES() 0x00 mstore + 0x20 0x00 return +} + +#define macro MULTI_HOURS() = takes(0) returns(0) { + 0x04 calldataload __HOURS() 0x00 mstore + 0x20 0x00 return +} + +#define macro MULTI_DAYS() = takes(0) returns(0) { + 0x04 calldataload __DAYS() 0x00 mstore + 0x20 0x00 return +} + +#define macro MULTI_WEEKS() = takes(0) returns(0) { + 0x04 calldataload __WEEKS() 0x00 mstore + 0x20 0x00 return +} + + + + + + + + + +// Function Dispatching +#define macro MAIN() = takes (1) returns (1) { + // Identify which function is being called. + // [func sig] + 0x00 calldataload 0xE0 shr + + + // function int104Max() pure returns (int256) + dup1 __FUNC_SIG(int104Max) eq int104MaxJump jumpi + + + // function int104Min() pure returns (int256) + dup1 __FUNC_SIG(int104Min) eq int104MinJump jumpi + + + // function int112Max() pure returns (int256) + dup1 __FUNC_SIG(int112Max) eq int112MaxJump jumpi + + + // function int112Min() pure returns (int256) + dup1 __FUNC_SIG(int112Min) eq int112MinJump jumpi + + + // function int120Max() pure returns (int256) + dup1 __FUNC_SIG(int120Max) eq int120MaxJump jumpi + + + // function int120Min() pure returns (int256) + dup1 __FUNC_SIG(int120Min) eq int120MinJump jumpi + + + // function int128Max() pure returns (int256) + dup1 __FUNC_SIG(int128Max) eq int128MaxJump jumpi + + + // function int128Min() pure returns (int256) + dup1 __FUNC_SIG(int128Min) eq int128MinJump jumpi + + + // function int136Max() pure returns (int256) + dup1 __FUNC_SIG(int136Max) eq int136MaxJump jumpi + + + // function int136Min() pure returns (int256) + dup1 __FUNC_SIG(int136Min) eq int136MinJump jumpi + + + // function int144Max() pure returns (int256) + dup1 __FUNC_SIG(int144Max) eq int144MaxJump jumpi + + + // function int144Min() pure returns (int256) + dup1 __FUNC_SIG(int144Min) eq int144MinJump jumpi + + + // function int152Max() pure returns (int256) + dup1 __FUNC_SIG(int152Max) eq int152MaxJump jumpi + + + // function int152Min() pure returns (int256) + dup1 __FUNC_SIG(int152Min) eq int152MinJump jumpi + + + // function int160Max() pure returns (int256) + dup1 __FUNC_SIG(int160Max) eq int160MaxJump jumpi + + + // function int160Min() pure returns (int256) + dup1 __FUNC_SIG(int160Min) eq int160MinJump jumpi + + + // function int168Max() pure returns (int256) + dup1 __FUNC_SIG(int168Max) eq int168MaxJump jumpi + + + // function int168Min() pure returns (int256) + dup1 __FUNC_SIG(int168Min) eq int168MinJump jumpi + + + // function int16Max() pure returns (int256) + dup1 __FUNC_SIG(int16Max) eq int16MaxJump jumpi + + + // function int16Min() pure returns (int256) + dup1 __FUNC_SIG(int16Min) eq int16MinJump jumpi + + + // function int176Max() pure returns (int256) + dup1 __FUNC_SIG(int176Max) eq int176MaxJump jumpi + + + // function int176Min() pure returns (int256) + dup1 __FUNC_SIG(int176Min) eq int176MinJump jumpi + + + // function int184Max() pure returns (int256) + dup1 __FUNC_SIG(int184Max) eq int184MaxJump jumpi + + + // function int184Min() pure returns (int256) + dup1 __FUNC_SIG(int184Min) eq int184MinJump jumpi + + + // function int192Max() pure returns (int256) + dup1 __FUNC_SIG(int192Max) eq int192MaxJump jumpi + + + // function int192Min() pure returns (int256) + dup1 __FUNC_SIG(int192Min) eq int192MinJump jumpi + + + // function int200Max() pure returns (int256) + dup1 __FUNC_SIG(int200Max) eq int200MaxJump jumpi + + + // function int200Min() pure returns (int256) + dup1 __FUNC_SIG(int200Min) eq int200MinJump jumpi + + + // function int208Max() pure returns (int256) + dup1 __FUNC_SIG(int208Max) eq int208MaxJump jumpi + + + // function int208Min() pure returns (int256) + dup1 __FUNC_SIG(int208Min) eq int208MinJump jumpi + + + // function int216Max() pure returns (int256) + dup1 __FUNC_SIG(int216Max) eq int216MaxJump jumpi + + + // function int216Min() pure returns (int256) + dup1 __FUNC_SIG(int216Min) eq int216MinJump jumpi + + + // function int224Max() pure returns (int256) + dup1 __FUNC_SIG(int224Max) eq int224MaxJump jumpi + + + // function int224Min() pure returns (int256) + dup1 __FUNC_SIG(int224Min) eq int224MinJump jumpi + + + // function int232Max() pure returns (int256) + dup1 __FUNC_SIG(int232Max) eq int232MaxJump jumpi + + + // function int232Min() pure returns (int256) + dup1 __FUNC_SIG(int232Min) eq int232MinJump jumpi + + + // function int240Max() pure returns (int256) + dup1 __FUNC_SIG(int240Max) eq int240MaxJump jumpi + + + // function int240Min() pure returns (int256) + dup1 __FUNC_SIG(int240Min) eq int240MinJump jumpi + + + // function int248Max() pure returns (int256) + dup1 __FUNC_SIG(int248Max) eq int248MaxJump jumpi + + + // function int248Min() pure returns (int256) + dup1 __FUNC_SIG(int248Min) eq int248MinJump jumpi + + + // function int24Max() pure returns (int256) + dup1 __FUNC_SIG(int24Max) eq int24MaxJump jumpi + + + // function int24Min() pure returns (int256) + dup1 __FUNC_SIG(int24Min) eq int24MinJump jumpi + + + // function int256Max() pure returns (int256) + dup1 __FUNC_SIG(int256Max) eq int256MaxJump jumpi + + + // function int256Min() pure returns (int256) + dup1 __FUNC_SIG(int256Min) eq int256MinJump jumpi + + + // function int32Max() pure returns (int256) + dup1 __FUNC_SIG(int32Max) eq int32MaxJump jumpi + + + // function int32Min() pure returns (int256) + dup1 __FUNC_SIG(int32Min) eq int32MinJump jumpi + + + // function int40Max() pure returns (int256) + dup1 __FUNC_SIG(int40Max) eq int40MaxJump jumpi + + + // function int40Min() pure returns (int256) + dup1 __FUNC_SIG(int40Min) eq int40MinJump jumpi + + + // function int48Max() pure returns (int256) + dup1 __FUNC_SIG(int48Max) eq int48MaxJump jumpi + + + // function int48Min() pure returns (int256) + dup1 __FUNC_SIG(int48Min) eq int48MinJump jumpi + + + // function int56Max() pure returns (int256) + dup1 __FUNC_SIG(int56Max) eq int56MaxJump jumpi + + + // function int56Min() pure returns (int256) + dup1 __FUNC_SIG(int56Min) eq int56MinJump jumpi + + + // function int64Max() pure returns (int256) + dup1 __FUNC_SIG(int64Max) eq int64MaxJump jumpi + + + // function int64Min() pure returns (int256) + dup1 __FUNC_SIG(int64Min) eq int64MinJump jumpi + + + // function int72Max() pure returns (int256) + dup1 __FUNC_SIG(int72Max) eq int72MaxJump jumpi + + + // function int72Min() pure returns (int256) + dup1 __FUNC_SIG(int72Min) eq int72MinJump jumpi + + + // function int80Max() pure returns (int256) + dup1 __FUNC_SIG(int80Max) eq int80MaxJump jumpi + + + // function int80Min() pure returns (int256) + dup1 __FUNC_SIG(int80Min) eq int80MinJump jumpi + + + // function int88Max() pure returns (int256) + dup1 __FUNC_SIG(int88Max) eq int88MaxJump jumpi + + + // function int88Min() pure returns (int256) + dup1 __FUNC_SIG(int88Min) eq int88MinJump jumpi + + + // function int8Max() pure returns (int256) + dup1 __FUNC_SIG(int8Max) eq int8MaxJump jumpi + + + // function int8Min() pure returns (int256) + dup1 __FUNC_SIG(int8Min) eq int8MinJump jumpi + + + // function int96Max() pure returns (int256) + dup1 __FUNC_SIG(int96Max) eq int96MaxJump jumpi + + + // function int96Min() pure returns (int256) + dup1 __FUNC_SIG(int96Min) eq int96MinJump jumpi + + + // function multiDays(uint256) pure returns (uint256) + dup1 __FUNC_SIG(multiDays) eq multiDaysJump jumpi + + + // function multiEther(uint256) pure returns (uint256) + dup1 __FUNC_SIG(multiEther) eq multiEtherJump jumpi + + + // function multiGwei(uint256) pure returns (uint256) + dup1 __FUNC_SIG(multiGwei) eq multiGweiJump jumpi + + + // function multiHours(uint256) pure returns (uint256) + dup1 __FUNC_SIG(multiHours) eq multiHoursJump jumpi + + + // function multiMinutes(uint256) pure returns (uint256) + dup1 __FUNC_SIG(multiMinutes) eq multiMinutesJump jumpi + + + // function multiSeconds(uint256) pure returns (uint256) + dup1 __FUNC_SIG(multiSeconds) eq multiSecondsJump jumpi + + + // function multiWeeks(uint256) pure returns (uint256) + dup1 __FUNC_SIG(multiWeeks) eq multiWeeksJump jumpi + + + // function multiWei(uint256) pure returns (uint256) + dup1 __FUNC_SIG(multiWei) eq multiWeiJump jumpi + + + // function oneDays() pure returns (uint256) + dup1 __FUNC_SIG(oneDays) eq oneDaysJump jumpi + + + // function oneEther() pure returns (uint256) + dup1 __FUNC_SIG(oneEther) eq oneEtherJump jumpi + + + // function oneGwei() pure returns (uint256) + dup1 __FUNC_SIG(oneGwei) eq oneGweiJump jumpi + + + // function oneHours() pure returns (uint256) + dup1 __FUNC_SIG(oneHours) eq oneHoursJump jumpi + + + // function oneMinutes() pure returns (uint256) + dup1 __FUNC_SIG(oneMinutes) eq oneMinutesJump jumpi + + + // function oneSeconds() pure returns (uint256) + dup1 __FUNC_SIG(oneSeconds) eq oneSecondsJump jumpi + + + // function oneWeeks() pure returns (uint256) + dup1 __FUNC_SIG(oneWeeks) eq oneWeeksJump jumpi + + + // function oneWei() pure returns (uint256) + dup1 __FUNC_SIG(oneWei) eq oneWeiJump jumpi + + + // function uint104Max() pure returns (uint256) + dup1 __FUNC_SIG(uint104Max) eq uint104MaxJump jumpi + + + // function uint112Max() pure returns (uint256) + dup1 __FUNC_SIG(uint112Max) eq uint112MaxJump jumpi + + + // function uint120Max() pure returns (uint256) + dup1 __FUNC_SIG(uint120Max) eq uint120MaxJump jumpi + + + // function uint128Max() pure returns (uint256) + dup1 __FUNC_SIG(uint128Max) eq uint128MaxJump jumpi + + + // function uint136Max() pure returns (uint256) + dup1 __FUNC_SIG(uint136Max) eq uint136MaxJump jumpi + + + // function uint144Max() pure returns (uint256) + dup1 __FUNC_SIG(uint144Max) eq uint144MaxJump jumpi + + + // function uint152Max() pure returns (uint256) + dup1 __FUNC_SIG(uint152Max) eq uint152MaxJump jumpi + + + // function uint160Max() pure returns (uint256) + dup1 __FUNC_SIG(uint160Max) eq uint160MaxJump jumpi + + + // function uint168Max() pure returns (uint256) + dup1 __FUNC_SIG(uint168Max) eq uint168MaxJump jumpi + + + // function uint16Max() pure returns (uint256) + dup1 __FUNC_SIG(uint16Max) eq uint16MaxJump jumpi + + + // function uint176Max() pure returns (uint256) + dup1 __FUNC_SIG(uint176Max) eq uint176MaxJump jumpi + + + // function uint184Max() pure returns (uint256) + dup1 __FUNC_SIG(uint184Max) eq uint184MaxJump jumpi + + + // function uint192Max() pure returns (uint256) + dup1 __FUNC_SIG(uint192Max) eq uint192MaxJump jumpi + + + // function uint200Max() pure returns (uint256) + dup1 __FUNC_SIG(uint200Max) eq uint200MaxJump jumpi + + + // function uint208Max() pure returns (uint256) + dup1 __FUNC_SIG(uint208Max) eq uint208MaxJump jumpi + + + // function uint216Max() pure returns (uint256) + dup1 __FUNC_SIG(uint216Max) eq uint216MaxJump jumpi + + + // function uint224Max() pure returns (uint256) + dup1 __FUNC_SIG(uint224Max) eq uint224MaxJump jumpi + + + // function uint232Max() pure returns (uint256) + dup1 __FUNC_SIG(uint232Max) eq uint232MaxJump jumpi + + + // function uint240Max() pure returns (uint256) + dup1 __FUNC_SIG(uint240Max) eq uint240MaxJump jumpi + + + // function uint248Max() pure returns (uint256) + dup1 __FUNC_SIG(uint248Max) eq uint248MaxJump jumpi + + + // function uint24Max() pure returns (uint256) + dup1 __FUNC_SIG(uint24Max) eq uint24MaxJump jumpi + + + // function uint256Max() pure returns (uint256) + dup1 __FUNC_SIG(uint256Max) eq uint256MaxJump jumpi + + + // function uint32Max() pure returns (uint256) + dup1 __FUNC_SIG(uint32Max) eq uint32MaxJump jumpi + + + // function uint40Max() pure returns (uint256) + dup1 __FUNC_SIG(uint40Max) eq uint40MaxJump jumpi + + + // function uint48Max() pure returns (uint256) + dup1 __FUNC_SIG(uint48Max) eq uint48MaxJump jumpi + + + // function uint56Max() pure returns (uint256) + dup1 __FUNC_SIG(uint56Max) eq uint56MaxJump jumpi + + + // function uint64Max() pure returns (uint256) + dup1 __FUNC_SIG(uint64Max) eq uint64MaxJump jumpi + + + // function uint72Max() pure returns (uint256) + dup1 __FUNC_SIG(uint72Max) eq uint72MaxJump jumpi + + + // function uint80Max() pure returns (uint256) + dup1 __FUNC_SIG(uint80Max) eq uint80MaxJump jumpi + + + // function uint88Max() pure returns (uint256) + dup1 __FUNC_SIG(uint88Max) eq uint88MaxJump jumpi + + + // function uint8Max() pure returns (uint256) + dup1 __FUNC_SIG(uint8Max) eq uint8MaxJump jumpi + + + // function uint96Max() pure returns (uint256) + dup1 __FUNC_SIG(uint96Max) eq uint96MaxJump jumpi + + not_found: + // Revert if no match is found. + 0x00 dup1 revert + + + // function uint168Max() pure returns (uint256) + uint168MaxJump: + UINT168_MAX() + + // function int184Max() pure returns (int256) + int184MaxJump: + INT184_MAX() + + // function int40Max() pure returns (int256) + int40MaxJump: + INT40_MAX() + + // function oneWeeks() pure returns (uint256) + oneWeeksJump: + ONE_WEEKS() + + // function uint160Max() pure returns (uint256) + uint160MaxJump: + UINT160_MAX() + + // function int176Min() pure returns (int256) + int176MinJump: + INT176_MIN() + + // function int88Max() pure returns (int256) + int88MaxJump: + INT88_MAX() + + // function int168Min() pure returns (int256) + int168MinJump: + INT168_MIN() + + // function int208Min() pure returns (int256) + int208MinJump: + INT208_MIN() + + // function uint104Max() pure returns (uint256) + uint104MaxJump: + UINT104_MAX() + + // function int24Min() pure returns (int256) + int24MinJump: + INT24_MIN() + + // function int112Min() pure returns (int256) + int112MinJump: + INT112_MIN() + + // function int96Max() pure returns (int256) + int96MaxJump: + INT96_MAX() + + // function int96Min() pure returns (int256) + int96MinJump: + INT96_MIN() + + // function uint128Max() pure returns (uint256) + uint128MaxJump: + UINT128_MAX() + + // function uint200Max() pure returns (uint256) + uint200MaxJump: + UINT200_MAX() + + // function oneHours() pure returns (uint256) + oneHoursJump: + ONE_HOURS() + + // function int144Min() pure returns (int256) + int144MinJump: + INT144_MIN() + + // function uint24Max() pure returns (uint256) + uint24MaxJump: + UINT24_MAX() + + // function uint120Max() pure returns (uint256) + uint120MaxJump: + UINT120_MAX() + + // function int256Max() pure returns (int256) + int256MaxJump: + INT256_MAX() + + // function int136Max() pure returns (int256) + int136MaxJump: + INT136_MAX() + + // function int216Max() pure returns (int256) + int216MaxJump: + INT216_MAX() + + // function int144Max() pure returns (int256) + int144MaxJump: + INT144_MAX() + + // function int72Min() pure returns (int256) + int72MinJump: + INT72_MIN() + + // function oneWei() pure returns (uint256) + oneWeiJump: + ONE_WEI() + + // function multiDays(uint256) pure returns (uint256) + multiDaysJump: + MULTI_DAYS() + + // function int64Min() pure returns (int256) + int64MinJump: + INT64_MIN() + + // function uint248Max() pure returns (uint256) + uint248MaxJump: + UINT248_MAX() + + // function int24Max() pure returns (int256) + int24MaxJump: + INT24_MAX() + + // function uint176Max() pure returns (uint256) + uint176MaxJump: + UINT176_MAX() + + // function int32Max() pure returns (int256) + int32MaxJump: + INT32_MAX() + + // function int232Max() pure returns (int256) + int232MaxJump: + INT232_MAX() + + // function int48Min() pure returns (int256) + int48MinJump: + INT48_MIN() + + // function multiSeconds(uint256) pure returns (uint256) + multiSecondsJump: + MULTI_SECONDS() + + // function int224Min() pure returns (int256) + int224MinJump: + INT224_MIN() + + // function int216Min() pure returns (int256) + int216MinJump: + INT216_MIN() + + // function int88Min() pure returns (int256) + int88MinJump: + INT88_MIN() + + // function uint136Max() pure returns (uint256) + uint136MaxJump: + UINT136_MAX() + + // function int248Min() pure returns (int256) + int248MinJump: + INT248_MIN() + + // function int176Max() pure returns (int256) + int176MaxJump: + INT176_MAX() + + // function uint8Max() pure returns (uint256) + uint8MaxJump: + UINT8_MAX() + + // function int56Max() pure returns (int256) + int56MaxJump: + INT56_MAX() + + // function int80Min() pure returns (int256) + int80MinJump: + INT80_MIN() + + // function int200Min() pure returns (int256) + int200MinJump: + INT200_MIN() + + // function uint48Max() pure returns (uint256) + uint48MaxJump: + UINT48_MAX() + + // function int192Max() pure returns (int256) + int192MaxJump: + INT192_MAX() + + // function int208Max() pure returns (int256) + int208MaxJump: + INT208_MAX() + + // function int40Min() pure returns (int256) + int40MinJump: + INT40_MIN() + + // function int192Min() pure returns (int256) + int192MinJump: + INT192_MIN() + + // function int64Max() pure returns (int256) + int64MaxJump: + INT64_MAX() + + // function multiHours(uint256) pure returns (uint256) + multiHoursJump: + MULTI_HOURS() + + // function int16Max() pure returns (int256) + int16MaxJump: + INT16_MAX() + + // function multiEther(uint256) pure returns (uint256) + multiEtherJump: + MULTI_ETHER() + + // function uint64Max() pure returns (uint256) + uint64MaxJump: + UINT64_MAX() + + // function uint216Max() pure returns (uint256) + uint216MaxJump: + UINT216_MAX() + + // function int248Max() pure returns (int256) + int248MaxJump: + INT248_MAX() + + // function int184Min() pure returns (int256) + int184MinJump: + INT184_MIN() + + // function oneGwei() pure returns (uint256) + oneGweiJump: + ONE_GWEI() + + // function int136Min() pure returns (int256) + int136MinJump: + INT136_MIN() + + // function int104Min() pure returns (int256) + int104MinJump: + INT104_MIN() + + // function uint40Max() pure returns (uint256) + uint40MaxJump: + UINT40_MAX() + + // function uint96Max() pure returns (uint256) + uint96MaxJump: + UINT96_MAX() + + // function multiMinutes(uint256) pure returns (uint256) + multiMinutesJump: + MULTI_MINUTES() + + // function uint72Max() pure returns (uint256) + uint72MaxJump: + UINT72_MAX() + + // function int56Min() pure returns (int256) + int56MinJump: + INT56_MIN() + + // function multiGwei(uint256) pure returns (uint256) + multiGweiJump: + MULTI_GWEI() + + // function int232Min() pure returns (int256) + int232MinJump: + INT232_MIN() + + // function uint224Max() pure returns (uint256) + uint224MaxJump: + UINT224_MAX() + + // function uint80Max() pure returns (uint256) + uint80MaxJump: + UINT80_MAX() + + // function int16Min() pure returns (int256) + int16MinJump: + INT16_MIN() + + // function int120Max() pure returns (int256) + int120MaxJump: + INT120_MAX() + + // function uint152Max() pure returns (uint256) + uint152MaxJump: + UINT152_MAX() + + // function multiWei(uint256) pure returns (uint256) + multiWeiJump: + MULTI_WEI() + + // function int200Max() pure returns (int256) + int200MaxJump: + INT200_MAX() + + // function uint144Max() pure returns (uint256) + uint144MaxJump: + UINT144_MAX() + + // function uint32Max() pure returns (uint256) + uint32MaxJump: + UINT32_MAX() + + // function uint184Max() pure returns (uint256) + uint184MaxJump: + UINT184_MAX() + + // function int128Min() pure returns (int256) + int128MinJump: + INT128_MIN() + + // function uint16Max() pure returns (uint256) + uint16MaxJump: + UINT16_MAX() + + // function int160Max() pure returns (int256) + int160MaxJump: + INT160_MAX() + + // function uint208Max() pure returns (uint256) + uint208MaxJump: + UINT208_MAX() + + // function int168Max() pure returns (int256) + int168MaxJump: + INT168_MAX() + + // function oneDays() pure returns (uint256) + oneDaysJump: + ONE_DAYS() + + // function oneMinutes() pure returns (uint256) + oneMinutesJump: + ONE_MINUTES() + + // function int120Min() pure returns (int256) + int120MinJump: + INT120_MIN() + + // function oneSeconds() pure returns (uint256) + oneSecondsJump: + ONE_SECONDS() + + // function int8Max() pure returns (int256) + int8MaxJump: + INT8_MAX() + + // function uint112Max() pure returns (uint256) + uint112MaxJump: + UINT112_MAX() + + // function int8Min() pure returns (int256) + int8MinJump: + INT8_MIN() + + // function oneEther() pure returns (uint256) + oneEtherJump: + ONE_ETHER() + + // function int72Max() pure returns (int256) + int72MaxJump: + INT72_MAX() + + // function int240Max() pure returns (int256) + int240MaxJump: + INT240_MAX() + + // function multiWeeks(uint256) pure returns (uint256) + multiWeeksJump: + MULTI_WEEKS() + + // function int32Min() pure returns (int256) + int32MinJump: + INT32_MIN() + + // function int80Max() pure returns (int256) + int80MaxJump: + INT80_MAX() + + // function int160Min() pure returns (int256) + int160MinJump: + INT160_MIN() + + // function uint256Max() pure returns (uint256) + uint256MaxJump: + UINT256_MAX() + + // function uint240Max() pure returns (uint256) + uint240MaxJump: + UINT240_MAX() + + // function uint192Max() pure returns (uint256) + uint192MaxJump: + UINT192_MAX() + + // function int112Max() pure returns (int256) + int112MaxJump: + INT112_MAX() + + // function uint56Max() pure returns (uint256) + uint56MaxJump: + UINT56_MAX() + + // function int256Min() pure returns (int256) + int256MinJump: + INT256_MIN() + + // function int48Max() pure returns (int256) + int48MaxJump: + INT48_MAX() + + // function int224Max() pure returns (int256) + int224MaxJump: + INT224_MAX() + + // function int128Max() pure returns (int256) + int128MaxJump: + INT128_MAX() + + // function int152Max() pure returns (int256) + int152MaxJump: + INT152_MAX() + + // function int240Min() pure returns (int256) + int240MinJump: + INT240_MIN() + + // function uint232Max() pure returns (uint256) + uint232MaxJump: + UINT232_MAX() + + // function int104Max() pure returns (int256) + int104MaxJump: + INT104_MAX() + + // function uint88Max() pure returns (uint256) + uint88MaxJump: + UINT88_MAX() + + // function int152Min() pure returns (int256) + int152MinJump: + INT152_MIN() +} + +/// @title Constants +/// @notice SPDX-License-Identifier: MIT +/// @author AmadiMichael +/// @notice common constants found in solidity and helpers in huff + + +// value constants +#define constant __ONE_WEI = 0x01 +#define constant __ONE_GWEI = 0x3b9aca00 +#define constant __ONE_ETHER = 0xde0b6b3a7640000 + + +// time constants +#define constant __ONE_SECONDS = 0x01 +#define constant __ONE_MINUTES = 0x3c +#define constant __ONE_HOURS = 0xe10 +#define constant __ONE_DAYS = 0x15180 +#define constant __ONE_WEEKS = 0x93a80 + + +// type ranges constants +#define constant __UINT256_MAX = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +#define constant __UINT248_MAX = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +#define constant __UINT240_MAX = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +#define constant __UINT232_MAX = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +#define constant __UINT224_MAX = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffff +#define constant __UINT216_MAX = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffff +#define constant __UINT208_MAX = 0xffffffffffffffffffffffffffffffffffffffffffffffffffff +#define constant __UINT200_MAX = 0xffffffffffffffffffffffffffffffffffffffffffffffffff +#define constant __UINT192_MAX = 0xffffffffffffffffffffffffffffffffffffffffffffffff +#define constant __UINT184_MAX = 0xffffffffffffffffffffffffffffffffffffffffffffff +#define constant __UINT176_MAX = 0xffffffffffffffffffffffffffffffffffffffffffff +#define constant __UINT168_MAX = 0xffffffffffffffffffffffffffffffffffffffffff +#define constant __UINT160_MAX = 0xffffffffffffffffffffffffffffffffffffffff +#define constant __UINT152_MAX = 0xffffffffffffffffffffffffffffffffffffff +#define constant __UINT144_MAX = 0xffffffffffffffffffffffffffffffffffff +#define constant __UINT136_MAX = 0xffffffffffffffffffffffffffffffffff +#define constant __UINT128_MAX = 0xffffffffffffffffffffffffffffffff +#define constant __UINT120_MAX = 0xffffffffffffffffffffffffffffff +#define constant __UINT112_MAX = 0xffffffffffffffffffffffffffff +#define constant __UINT104_MAX = 0xffffffffffffffffffffffffff +#define constant __UINT96_MAX = 0xffffffffffffffffffffffff +#define constant __UINT88_MAX = 0xffffffffffffffffffffff +#define constant __UINT80_MAX = 0xffffffffffffffffffff +#define constant __UINT72_MAX = 0xffffffffffffffffff +#define constant __UINT64_MAX = 0xffffffffffffffff +#define constant __UINT56_MAX = 0xffffffffffffff +#define constant __UINT48_MAX = 0xffffffffffff +#define constant __UINT40_MAX = 0xffffffffff +#define constant __UINT32_MAX = 0xffffffff +#define constant __UINT24_MAX = 0xffffff +#define constant __UINT16_MAX = 0xffff +#define constant __UINT8_MAX = 0xff + + +#define constant __INT256_MAX = 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +#define constant __INT248_MAX = 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +#define constant __INT240_MAX = 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +#define constant __INT232_MAX = 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffff +#define constant __INT224_MAX = 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffff +#define constant __INT216_MAX = 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffff +#define constant __INT208_MAX = 0x7fffffffffffffffffffffffffffffffffffffffffffffffffff +#define constant __INT200_MAX = 0x7fffffffffffffffffffffffffffffffffffffffffffffffff +#define constant __INT192_MAX = 0x7fffffffffffffffffffffffffffffffffffffffffffffff +#define constant __INT184_MAX = 0x7fffffffffffffffffffffffffffffffffffffffffffff +#define constant __INT176_MAX = 0x7fffffffffffffffffffffffffffffffffffffffffff +#define constant __INT168_MAX = 0x7fffffffffffffffffffffffffffffffffffffffff +#define constant __INT160_MAX = 0x7fffffffffffffffffffffffffffffffffffffff +#define constant __INT152_MAX = 0x7fffffffffffffffffffffffffffffffffffff +#define constant __INT144_MAX = 0x7fffffffffffffffffffffffffffffffffff +#define constant __INT136_MAX = 0x7fffffffffffffffffffffffffffffffff +#define constant __INT128_MAX = 0x7fffffffffffffffffffffffffffffff +#define constant __INT120_MAX = 0x7fffffffffffffffffffffffffffff +#define constant __INT112_MAX = 0x7fffffffffffffffffffffffffff +#define constant __INT104_MAX = 0x7fffffffffffffffffffffffff +#define constant __INT96_MAX = 0x7fffffffffffffffffffffff +#define constant __INT88_MAX = 0x7fffffffffffffffffffff +#define constant __INT80_MAX = 0x7fffffffffffffffffff +#define constant __INT72_MAX = 0x7fffffffffffffffff +#define constant __INT64_MAX = 0x7fffffffffffffff +#define constant __INT56_MAX = 0x7fffffffffffff +#define constant __INT48_MAX = 0x7fffffffffff +#define constant __INT40_MAX = 0x7fffffffff +#define constant __INT32_MAX = 0x7fffffff +#define constant __INT24_MAX = 0x7fffff +#define constant __INT16_MAX = 0x7fff +#define constant __INT8_MAX = 0x7f + +#define constant __INT256_MIN = 0x8000000000000000000000000000000000000000000000000000000000000000 +#define constant __INT248_MIN = 0xff80000000000000000000000000000000000000000000000000000000000000 +#define constant __INT240_MIN = 0xffff800000000000000000000000000000000000000000000000000000000000 +#define constant __INT232_MIN = 0xffffff8000000000000000000000000000000000000000000000000000000000 +#define constant __INT224_MIN = 0xffffffff80000000000000000000000000000000000000000000000000000000 +#define constant __INT216_MIN = 0xffffffffff800000000000000000000000000000000000000000000000000000 +#define constant __INT208_MIN = 0xffffffffffff8000000000000000000000000000000000000000000000000000 +#define constant __INT200_MIN = 0xffffffffffffff80000000000000000000000000000000000000000000000000 +#define constant __INT192_MIN = 0xffffffffffffffff800000000000000000000000000000000000000000000000 +#define constant __INT184_MIN = 0xffffffffffffffffff8000000000000000000000000000000000000000000000 +#define constant __INT176_MIN = 0xffffffffffffffffffff80000000000000000000000000000000000000000000 +#define constant __INT168_MIN = 0xffffffffffffffffffffff800000000000000000000000000000000000000000 +#define constant __INT160_MIN = 0xffffffffffffffffffffffff8000000000000000000000000000000000000000 +#define constant __INT152_MIN = 0xffffffffffffffffffffffffff80000000000000000000000000000000000000 +#define constant __INT144_MIN = 0xffffffffffffffffffffffffffff800000000000000000000000000000000000 +#define constant __INT136_MIN = 0xffffffffffffffffffffffffffffff8000000000000000000000000000000000 +#define constant __INT128_MIN = 0xffffffffffffffffffffffffffffffff80000000000000000000000000000000 +#define constant __INT120_MIN = 0xffffffffffffffffffffffffffffffffff800000000000000000000000000000 +#define constant __INT112_MIN = 0xffffffffffffffffffffffffffffffffffff8000000000000000000000000000 +#define constant __INT104_MIN = 0xffffffffffffffffffffffffffffffffffffff80000000000000000000000000 +#define constant __INT96_MIN = 0xffffffffffffffffffffffffffffffffffffffff800000000000000000000000 +#define constant __INT88_MIN = 0xffffffffffffffffffffffffffffffffffffffffff8000000000000000000000 +#define constant __INT80_MIN = 0xffffffffffffffffffffffffffffffffffffffffffff80000000000000000000 +#define constant __INT72_MIN = 0xffffffffffffffffffffffffffffffffffffffffffffff800000000000000000 +#define constant __INT64_MIN = 0xffffffffffffffffffffffffffffffffffffffffffffffff8000000000000000 +#define constant __INT56_MIN = 0xffffffffffffffffffffffffffffffffffffffffffffffffff80000000000000 +#define constant __INT48_MIN = 0xffffffffffffffffffffffffffffffffffffffffffffffffffff800000000000 +#define constant __INT40_MIN = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffff8000000000 +#define constant __INT32_MIN = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffff80000000 +#define constant __INT24_MIN = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffff800000 +#define constant __INT16_MIN = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8000 +#define constant __INT8_MIN = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80 + + + +// value helpers +// if you don't mind an extra 8 gas then these helper functions can be "helpful" + + +#define macro __WEI() = takes(1) returns(1) { + // expects at least one item on the stack (amount(x) of wei) + // [x, ...] + [__ONE_WEI] mul // [x_wei, ...] +} + +#define macro __GWEI() = takes(1) returns(1) { + // expects at least one item on the stack (amount(x) of gwei) + // [x, ...] + [__ONE_GWEI] mul // [x_gwei, ...] +} + +#define macro __ETHER() = takes(1) returns(1) { + // expects at least one item on the stack (amount(x) of ether) + // [x, ...] + [__ONE_ETHER] mul // [x_ether, ...] +} + + + + +// time helpers +#define macro __SECONDS() = takes(1) returns(1) { + // expects at least one item on the stack (amount(x) of seconds) + // [x, ...] + [__ONE_SECONDS] mul // [x_seconds, ...] +} + +#define macro __MINUTES() = takes(1) returns(1) { + // expects at least one item on the stack (amount(x) of minutes) + // [x, ...] + [__ONE_MINUTES] mul // [x_minutes, ...] +} + +#define macro __HOURS() = takes(1) returns(1) { + // expects at least one item on the stack (amount(x) of hours) + // [x, ...] + [__ONE_HOURS] mul // [x_hours, ...] +} + +#define macro __DAYS() = takes(1) returns(1) { + // expects at least one item on the stack (amount(x) of days) + // [x, ...] + [__ONE_DAYS] mul // [x_days, ...] +} + +#define macro __WEEKS() = takes(1) returns(1) { + // expects at least one item on the stack (amount(x) of weeks) + // [x, ...] + [__ONE_WEEKS] mul // [x_weeks, ...] +} \ No newline at end of file diff --git a/src/utils/__TEMP__eyomwxkixnogyzbecekrqolgmjnwpgibLibBit.huff b/src/utils/__TEMP__eyomwxkixnogyzbecekrqolgmjnwpgibLibBit.huff new file mode 100644 index 00000000..2ee77790 --- /dev/null +++ b/src/utils/__TEMP__eyomwxkixnogyzbecekrqolgmjnwpgibLibBit.huff @@ -0,0 +1,267 @@ +#define function fls(uint256) pure returns (uint256) +#define function ffs(uint256) pure returns (uint256) +#define function popCount(uint256) pure returns (uint256) +#define function isPowOf2(uint256) pure returns (uint256) + +#define macro FLS_WRAPPER() = { + 0x04 calldataload + FLS() + + 0x00 mstore + 0x20 0x00 return +} + +#define macro FFS_WRAPPER() = { + 0x04 calldataload + FFS() + + 0x00 mstore + 0x20 0x00 return +} + +#define macro POP_COUNT_WRAPPER() = { + 0x04 calldataload + POP_COUNT() + + 0x00 mstore + 0x20 0x00 return +} + +#define macro IS_POW_OF_2_WRAPPER() = { + 0x04 calldataload + IS_POW_OF_2() + + 0x00 mstore + 0x20 0x00 return +} + +#define macro MAIN() = { + pc calldataload 0xE0 shr + dup1 __FUNC_SIG(fls) eq fls jumpi + dup1 __FUNC_SIG(ffs) eq ffs jumpi + dup1 __FUNC_SIG(popCount) eq pop_count jumpi + dup1 __FUNC_SIG(isPowOf2) eq is_pow_of_2 jumpi + + 0x00 dup1 revert + + fls: + FLS_WRAPPER() + ffs: + FFS_WRAPPER() + pop_count: + POP_COUNT_WRAPPER() + is_pow_of_2: + IS_POW_OF_2_WRAPPER() +} + + +/// @title LibBit +/// @notice SPDX-License-Identifier: MIT +/// @author Vectorized +/// @author Solady (https://github.com/Vectorized/solady/blob/main/src/utils/LibBit.sol) +/// @author Inspired by (https://graphics.stanford.edu/~seander/bithacks.html) +/// @author clabby +/// @notice Various bit-twiddling macros. + +#define constant A = 0xffffffffffffffffffffffffffffffff +#define constant B = 0xffffffffffffffff +#define constant C = 0xffffffff + +#define constant FLS_DEBRUIJN = 0x0009010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f +#define constant FFS_DEBRUIJN = 0x00011c021d0e18031e16140f191104081f1b0d17151310071a0c12060b050a09 + +/// @dev Returns the index of the most significant bit of `x`. +/// If `x` is zero, returns 256. +#define macro FLS() = takes (1) returns (1) { + // Input stack: [x] + + dup1 iszero // [x == 0, x] + 0x08 shl // [(x == 0) << 0x08, x] + + dup2 [A] lt // [A < x, r, x] + 0x07 shl // [(A < x) << 0x07, r, x] + or // [r, x] + + dup2 dup2 shr // [x >> r, r, x] + [B] lt // [B < (x >> r), r, x] + 0x06 shl // [(B < (x >> r)) << 0x06, r, x] + or // [r, x] + + dup2 dup2 shr // [x >> r, r, x] + [C] lt // [C < (x >> r), r, x] + 0x05 shl // [(C < (x >> r)) << 0x05, r, x] + or // [r, x] + + // For the remaining 32 bits, use a De Bruijn lookup. + swap1 dup2 shr // [x >> r, r] + dup1 0x01 shr // [(x >> r) >> 0x01, x >> r, r] + or // [x, r] + + dup1 0x02 shr // [x >> 0x02, x, r] + or // [x, r] + + dup1 0x04 shr // [x >> 0x04, x, r] + or // [x, r] + + dup1 0x08 shr // [x >> 0x08, x, r] + or // [x, r] + + dup1 0x10 shr // [x >> 0x10, r] + or // [x, r] + + // Note: This does increase final code size, can shift left by 224 at runtime + // if codesize is more of a concern. + __RIGHTPAD(0x07c4acdd) // [0x07c4acdd (right padded), x, r] + mul // [x * 0x07c4acdd, r] + 0xFB shr // [(x * 0x07c4acdd) >> 0xFB, r] + [FLS_DEBRUIJN] swap1 // [(x * 0x07c4acdd) >> 0xFB, debruijn_lookup, r] + byte // [b, r] + or // [b | r] + + // Return stack: [r] +} + +/// @dev Returns the index of the least significant bit of `x`. +/// If `x` is zero, returns 256. +#define macro FFS() = takes (1) returns (1) { + // Input stack: [x] + + dup1 iszero // [x == 0, x] + 0x08 shl // [(x == 0) << 0x08, x] + + // Isolate the least significant bit. + swap1 dup1 // [x, x, r] + not 0x01 add // [~x + 1, x, r] + and // [x, r] + + swap1 dup2 // [x, r, x] + [A] lt // [A < x, r, x] + 0x07 shl // [(A < x) << 0x07, r, x] + or // [r, x] + + dup2 dup2 shr // [x >> r, r, x] + [B] lt // [B < (x >> r), r, x] + 0x06 shl // [(B < (x >> r)) << 0x06, r, x] + or // [r, x] + + dup2 dup2 shr // [x >> r, r, x] + [C] lt // [C < (x >> r), r, x] + 0x05 shl // [(C < (x >> r)) << 0x05] + or // [r, x] + + // For the remaining 32 bits, use a De Bruijn lookup. + + // Note: This does increase final code size, can shift left by 224 at runtime + // if codesize is more of a concern. + swap1 dup2 shr // [x >> r, r] + __RIGHTPAD(0x077cb531) // [0x077cb531..., x >> r, r] + mul // [(x >> r) * 0x077cb531, r] + 0xFB shr // [(x * 0x077cb531) >> 0xFB, r] + [FFS_DEBRUIJN] swap1 // [(x * 0x077cb531) >> 0xFB, debruijn_lookup, r] + byte // [b, r] + or // [b | r] + + // Return stack: [r] +} + +/// @dev Returns the number of set bits in `x`. +#define macro POP_COUNT() = takes (1) returns (1) { + // Input stack: [x] + + 0x00 not // [max, x] + dup1 dup3 lt // [is_not_max, max, x] + + swap2 // [x, max, is_not_max] + 0x03 dup3 div // [max / 0x03, x, max, is_not_max] + dup2 0x01 shr // [x >> 0x01, max / 0x03, x, max, is_not_max] + and // [(x >> 0x01) & (max / 0x03), x, max, is_not_max] + swap1 sub // [x, max, is_not_max] + + 0x05 dup3 div // [max / 0x05, x, max, is_not_max] + dup1 // [max / 0x05, max / 0x05, x, max, is_not_max] + dup3 0x02 shr // [x >> 0x02, max / 0x05, max / 0x05 x, max, is_not_max] + and // [(x >> 0x02) & (max / 0x05), max / 0x05, x, max, is_not_max] + swap2 // [max / 0x05, x, (x >> 0x02) & (max / 0x05), max, is_not_max] + and add // [x, max, is_not_max] + + 0x11 dup3 div // [max / 0x11, x, max, is_not_max] + swap1 // [x, max / 0x11, max, is_not_max] + dup1 0x04 shr // [x >> 0x04, x, max / 0x11, max, is_not_max] + add and // [x, max, is_not_max] + + swap1 0xFF // [0xFF, max, x, is_not_max] + swap1 div // [max / 0xFF, x, is_not_max] + mul // [(max / 0xFF) * x, is_not_max] + 0xF8 shr // [((max / 0xFF) * x) >> 0xF8, is_not_max] + 0x100 xor // [((max / 0xFF) * x) >> 0xF8) ^ 0x100, is_not_max] + mul // [((((max / 0xFF) * x) >> 0xF8) ^ 0x100) * is_not_max] + 0x100 xor // [(((((max / 0xFF) * x) >> 0xF8) ^ 0x100) * is_not_max) ^ 0x100] + + // Return stack: [c] +} + +/// @dev Returns 1, if the input is a power of 2. +#define macro IS_POW_OF_2() = takes (1) returns (1) { + // Input stack: [x] + + 0x01 // [1,x] + dup2 // [x,1,x] + sub // [x-1,x] + dup2 // [x,x-1,x] + and // [x & x-1,x] + swap1 // [x, x&x-1] + iszero // [x==0, x&x-1] + add // [(x==0) + (x&x-1)] + iszero // [(x==0) + (x&x-1) == 0] + + // Return stack: [c] +} + + +#define test FLS() = { + 0xFF 0x03 shl + FLS() + + 0x0a eq succeed jumpi + 0x00 dup1 revert + + succeed: +} + +#define test FFS() = { + 0xFF 0x03 shl + FFS() + + 0x03 eq succeed jumpi + 0x00 dup1 revert + + succeed: +} + +#define test POP_COUNT() = { + 0x01 dup1 + 0xFF shl or + POP_COUNT() + + 0x02 eq succeed jumpi + 0x00 dup1 revert + + succeed: +} + +#define test IS_POW_OF_2() = { + 0x05 dup1 + IS_POW_OF_2() + + 0x00 eq next jumpi + 0x00 dup1 revert + + next: + 0x08 dup1 + IS_POW_OF_2() + + 0x01 eq succeed jumpi + 0x00 dup1 revert + + succeed: +} \ No newline at end of file diff --git a/src/utils/__TEMP__fipsesfweqvmnghgiyyjyzxhruyzqbslBitPackLib.huff b/src/utils/__TEMP__fipsesfweqvmnghgiyyjyzxhruyzqbslBitPackLib.huff new file mode 100644 index 00000000..01993e90 --- /dev/null +++ b/src/utils/__TEMP__fipsesfweqvmnghgiyyjyzxhruyzqbslBitPackLib.huff @@ -0,0 +1,104 @@ +#define function packValue(bytes32, uint256, uint256, uint256) pure returns (bytes32) +#define function unpackValueFromRight(bytes32, uint256) pure returns (uint256) +#define function unpackValueFromLeft(bytes32, uint256) pure returns (uint256) +#define function unpackValueFromCenter(bytes32, uint256, uint256) pure returns (uint256) + +#define macro PACK_VALUE_WRAPPER() = takes (0) returns (0) { + 0x04 calldataload // [word] + 0x24 calldataload // [value, word] + 0x44 calldataload // [index, value, word] + 0x64 calldataload // [length, index, value, word] + PACK_VALUE() // [new_word] + 0x00 mstore // [] + 0x20 0x00 return +} + +#define macro UNPACK_FROM_RIGHT_WRAPPER() = takes (0) returns (0) { + 0x04 calldataload // [word] + 0x24 calldataload // [length, word] + UNPACK_FROM_RIGHT() // [value] + 0x00 mstore // [] + 0x20 0x00 return +} + +#define macro UNPACK_FROM_LEFT_WRAPPER() = takes (0) returns (0) { + 0x04 calldataload // [word] + 0x24 calldataload // [length, word] + UNPACK_FROM_LEFT() // [value] + 0x00 mstore // [] + 0x20 0x00 return +} + +#define macro UNPACK_FROM_CENTER_WRAPPER() = takes (0) returns (0) { + 0x04 calldataload // [word] + 0x24 calldataload // [length, word] + 0x44 calldataload // [length, index, word] + UNPACK_FROM_CENTER() // [value] + 0x00 mstore // [] + 0x20 0x00 return +} + +#define macro MAIN() = takes (0) returns (0) { + // Identify which function is being called using the 4 byte function signature + pc calldataload 0xE0 shr + + dup1 __FUNC_SIG(packValue) eq packValue jumpi + dup1 __FUNC_SIG(unpackValueFromRight) eq unpackValueFromRight jumpi + dup1 __FUNC_SIG(unpackValueFromLeft) eq unpackValueFromLeft jumpi + dup1 __FUNC_SIG(unpackValueFromCenter) eq unpackValueFromCenter jumpi + + 0x00 0x00 revert + + packValue: + PACK_VALUE_WRAPPER() + unpackValueFromRight: + UNPACK_FROM_RIGHT_WRAPPER() + unpackValueFromLeft: + UNPACK_FROM_LEFT_WRAPPER() + unpackValueFromCenter: + UNPACK_FROM_CENTER_WRAPPER() +} + +/// @title BitPackLib +/// @notice SPDX-License-Identifier: MIT +/// @author kadenzipfel +/// @notice Efficient bit packing library + +#define constant MAX = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + +/// @notice Packs value of given length at index of given word +/// @dev Assumes index < 256 - length +#define macro PACK_VALUE() = takes (4) returns (1) { + // Input stack: // [length, index, value, word] + 0x100 sub sub // [shift, value, word] + shl or // [new_word] +} + +/// @notice Unpacks value of given length from right of word +/// @dev word & (~0 >> (256 - length)) +#define macro UNPACK_FROM_RIGHT() = takes (2) returns (1) { + // Input stack: // [length, word] + [MAX] // [not(0), length, word] + swap1 0x100 sub // [offset, not(0), word] + shr and // [value] +} + +/// @notice Unpacks value of given length from left of word +/// @dev word >> (256 - length) +#define macro UNPACK_FROM_LEFT() = takes (2) returns (1) { + // Input stack: // [length, word] + 0x100 sub // [shift, word] + shr // [value] +} + +/// @notice Unpacks value of given length from index of word +/// @dev Assumes index < 256 - length +/// (word & ((~0 >> 256 - length) << (256 - length - index))) >> (256 - length - index) +#define macro UNPACK_FROM_CENTER() = takes (3) returns (1) { + // Input stack: // [length, index, word] + 0x100 sub // [256 - length, index, word] + swap1 dup2 sub // [256 - length - index, 256 - length, word] + [MAX] swap1 swap2 shr // [~0 >> 256 - length, 256 - length - index, word] + dup2 shl swap1 swap2 and // [(word & ((~0 >> 256 - length) << (256 - length - index))), 256 - length - index] + swap1 shr // [value] +} diff --git a/src/utils/__TEMP__flqjyauokblaazsrdhqxfgjsonhnpjloMerkleProofLib.huff b/src/utils/__TEMP__flqjyauokblaazsrdhqxfgjsonhnpjloMerkleProofLib.huff new file mode 100644 index 00000000..f55d7ee8 --- /dev/null +++ b/src/utils/__TEMP__flqjyauokblaazsrdhqxfgjsonhnpjloMerkleProofLib.huff @@ -0,0 +1,86 @@ +#define function verifyProof(bytes32, bytes32, bytes32[] calldata) pure returns (bool) + +#define macro VERIFY_PROOF_WRAPPER() = takes (0) returns (0) { + 0x04 calldataload // [root] + 0x24 calldataload // [leaf, root] + 0x64 // [proof_cd_ptr, leaf, root] + VERIFY_PROOF() // [is_valid] + 0x00 mstore // [] + 0x20 0x00 return +} + +#define macro MAIN() = takes (0) returns (0) { + pc calldataload 0xE0 shr + dup1 __FUNC_SIG(verifyProof) eq verifyProof jumpi + + 0x00 dup1 revert + + verifyProof: + VERIFY_PROOF_WRAPPER() +} + + +/// @title MerkleProofLib +/// @notice SPDX-License-Identifier: MIT +/// @author clabby +/// @notice Gas optimized merkle proof verification library +/// @notice Adapted from Solmate (https://github.com/transmissions11/solmate/blob/v7/src/utils/MerkleProofLib.sol) +/// @dev The `proof_cd_ptr` passed via the stack to this macro should point to the offset +/// of the proof array's length in the calldata. This macro assumes that the proof +/// array contains 32 byte values. + +/// @notice Verifies a merkle proof. +/// @param proof_cd_ptr Pointer to the length of the proof array. +/// @param leaf Leaf to prove inclusion of +/// @param root Root of the merkle tree +/// @return is_valid True if the inclusion of `leaf` in the merkle tree represented by +/// `root` was able to be proven, false if not. +#define macro VERIFY_PROOF() = takes (3) returns (1) { + // Input Stack: [proof_cd_ptr, leaf, root] + + // Get ending offset (ptr + 1 + proof_len * 0x20) of proof array + // and its starting offset (ptr + 0x20) + dup1 + 0x20 add + swap1 // [proof_cd_ptr, proof_cd_ptr + 0x20, leaf, root] + calldataload // [proof_arr_len, proof_cd_ptr + 0x20, leaf, root] + 0x05 shl // [proof_arr_len << 5, proof_cd_ptr + 0x20, leaf, root] + dup2 add // [proof_arr_len << 5 + proof_cd_ptr + 0x20, proof_cd_ptr + 0x20, leaf, root] + + // Stack description changed to reflect the vars' respective purposes in the loop + swap1 // [loop_offset, proof_arr_end, computed_hash, root] + + loop: + dup2 dup2 // [loop_offset, proof_arr_end, loop_offset, proof_arr_end, computed_hash, root] + lt // [loop_offset < proof_arr_end, loop_offset, proof_arr_end, computed_hash, root] + // If loop index is >= the proof arr end offset, finish the loop + iszero finish jumpi + + // Load data at proof_arr[loop_offset] + dup1 // [loop_offset, loop_offset, proof_arr_end, computed_hash, root] + calldataload // [proof_arr[loop_offset], loop_offset, proof_arr_end, computed_hash, root] + + dup1 // [proof_arr[loop_offset], proof_arr[loop_offset], loop_offset, proof_arr_end, computed_hash, root] + dup5 // [computed_hash, proof_arr[loop_offset], proof_arr[loop_offset], loop_offset, proof_arr_end, computed_hash, root] + gt // [computed_hash > proof_arr[loop_offset], proof_arr[loop_offset], loop_offset, proof_arr_end, computed_hash, root] + 0x05 shl // [(computed_hash > proof_arr[loop_offset]) << 5, proof_arr[loop_offset], loop_offset, proof_arr_end, computed_hash, root] + + dup5 // [computed_hash, (computed_hash > proof_arr[loop_offset]) << 5, proof_arr[loop_offset], loop_offset, proof_arr_end, computed_hash, root] + dup2 // [(computed_hash > proof_arr[loop_offset]) << 5, computed_hash, (computed_hash > proof_arr[loop_offset]) << 5, proof_arr[loop_offset], loop_offset, proof_arr_end, computed_hash, root] + mstore // [(computed_hash > proof_arr[loop_offset]) << 5, proof_arr[loop_offset], loop_offset, proof_arr_end, computed_hash, root] + + 0x20 xor // [((computed_hash > proof_arr[loop_offset]) << 5) ^ 0x20, proof_arr[loop_offset], loop_offset, proof_arr_end, computed_hash, root] + mstore // [loop_offset, proof_arr_end, computed_hash, root] + + // Compute new hash + 0x40 0x00 sha3 // [computed_hash_new, loop_offset, proof_arr_end, computed_hash, root] + swap3 pop // [loop_offset, proof_arr_end, computed_hash, root] + + // Increment loop offset by 0x20 + 0x20 add // [loop_offset + 0x20, proof_arr_end, computed_hash, root] + + loop jump + finish: + pop pop // [root, computed_hash] + eq // [root == computed_hash] +} \ No newline at end of file diff --git a/src/utils/__TEMP__fsghwzbaphyfhugpyejapdmpmaanfaqcTSOwnable.huff b/src/utils/__TEMP__fsghwzbaphyfhugpyejapdmpmaanfaqcTSOwnable.huff new file mode 100644 index 00000000..ec480907 --- /dev/null +++ b/src/utils/__TEMP__fsghwzbaphyfhugpyejapdmpmaanfaqcTSOwnable.huff @@ -0,0 +1,172 @@ +/// SPDX-License-Identifier: MIT + +#define macro CONSTRUCTOR() = takes (0) returns (0) { + TSOWNABLE_CONSTRUCTOR() +} + +#define macro MAIN() = takes (0) returns (0) { + pc calldataload 0xe0 shr // [sig] + TSOWNABLE_MAIN() // [sig] + 0x00 dup1 revert // [] +} + +/// @title TSOwnable +/// @notice SPDX-License-Identifier: MIT +/// @author merkleplant (modified by @devtooligan) +/// @author asnared +/// @notice An Ownable Implementation using Two-Step Transfer Pattern + +#include "./Address.huff" +#include "./CommonErrors.huff" +#include "../auth/NonPayable.huff" + +// External Interface + +/// @notice Returns the current owner address. +#define function owner() view returns (address) + +/// @notice Returns the current pending owner address. +#define function pendingOwner() view returns (address) + +/// @notice Sets the pending owner address. +/// @dev Only callable by owner. +#define function setPendingOwner(address) nonpayable returns () + +/// @notice Accepts the ownership. +/// @dev Only callable by pending owner. +#define function acceptOwnership() nonpayable returns () + +/// @notice Emitted when new owner set. +#define event NewOwner(address, address) + +/// @notice Emitted when new pending owner set. +#define event NewPendingOwner(address, address) + +// Storage + +/// @notice Owner Storage Slot +#define constant OWNER_SLOT = FREE_STORAGE_POINTER() + +/// @notice Pending Owner Storage Slot +#define constant PENDING_OWNER_SLOT = FREE_STORAGE_POINTER() + +/// @notice Inner TSOwnable Constructor +#define macro TSOWNABLE_CONSTRUCTOR() = takes (0) returns (0) { + // Store msg.sender as owner + caller [OWNER_SLOT] sstore // [] +} + +/// @notice Only Owner Modifier +#define macro ONLY_OWNER_MODIFIER() = takes (0) returns (0) { + [OWNER_SLOT] sload // [owner] + caller eq authed jumpi // [] + ONLY_OWNER(0x00) // [] + authed: // [] +} + +/// @notice Only Pending Owner Modifier +#define macro ONLY_PENDING_OWNER_MODIFIER() = takes (0) returns (0) { + [PENDING_OWNER_SLOT] sload // [pending_owner] + caller eq // [msg.sender == pending_owner] + authed jumpi // [] + ONLY_PENDING_OWNER(0x00) // [] + authed: // [] +} + +// Mutating Functions + +/// @notice Set Pending Owner +/// @param newOwner The address of the new pending owner +#define macro OWNABLE_SET_PENDING_OWNER() = takes (0) returns (0) { + NON_PAYABLE() // [] + ONLY_OWNER_MODIFIER() // [] + + // Read argument and mask to address + 0x04 calldataload MASK_ADDRESS() // [newOwner] + + // Revert if address equals owner + dup1 caller // [owner, newOwner, newOwner] + eq iszero set jumpi // [newOwner] + ALREADY_OWNER(0x00) // [] + set: // [newOwner] + + // Duplicate address on stack + dup1 // [newOwner, newOwner] + + // Emit NewPendingOwner event + [OWNER_SLOT] sload // [owner, newOwner, newOwner] + __EVENT_HASH(NewPendingOwner) 0x00 0x00 // [offset, size, sig, owner, newOwner, newOwner] + log3 // [newOwner] + + // Store address as pending owner + [PENDING_OWNER_SLOT] sstore // [] + + // Stop execution + stop +} + +/// @notice Accept Ownership +/// @notice Allows the pending owner to become the owner +#define macro OWNABLE_ACCEPT_OWNERSHIP() = takes (0) returns (0) { + NON_PAYABLE() // [] + ONLY_PENDING_OWNER_MODIFIER() // [] + + // Emit NewOwner event + caller [OWNER_SLOT] sload // [owner, pending_owner] + __EVENT_HASH(NewOwner) 0x00 0x00 // [offset, size, sig, owner, pending_owner] + log3 // [] + + // Store msg.sender as owner + caller [OWNER_SLOT] sstore // [] + + // Clear pending owner + 0x00 [PENDING_OWNER_SLOT] sstore // [] + + // Stop execution + stop +} + +// View Functions + +/// @notice Get Owner +/// @notice Returns the current owner +#define macro OWNABLE_GET_OWNER() = takes (0) returns (0) { + NON_PAYABLE() // [] + [OWNER_SLOT] sload // [owner] + 0x00 mstore // [] + 0x20 0x00 return // [] +} + +/// @notice Get Pending Owner +/// @notice Returns the current pending owner +#define macro OWNABLE_GET_PENDING_OWNER() = takes (0) returns (0) { + NON_PAYABLE() // [] + [PENDING_OWNER_SLOT] sload // [pending_owner] + 0x00 mstore // [] + 0x20 0x00 return // [] +} + +// Function Dispatching +#define macro TSOWNABLE_MAIN() = takes (1) returns (1) { + // Input stack: [sig] + // Output stack: [sig] + + dup1 __FUNC_SIG(setPendingOwner) eq set_pending_owner jumpi + dup1 __FUNC_SIG(acceptOwnership) eq accept_ownership jumpi + dup1 __FUNC_SIG(owner) eq get_owner jumpi + dup1 __FUNC_SIG(pendingOwner) eq get_pending_owner jumpi + + // Bubble up to the parent macro + no_match jump + + set_pending_owner: + OWNABLE_SET_PENDING_OWNER() + accept_ownership: + OWNABLE_ACCEPT_OWNERSHIP() + get_owner: + OWNABLE_GET_OWNER() + get_pending_owner: + OWNABLE_GET_PENDING_OWNER() + + no_match: +} diff --git a/src/utils/__TEMP__fvsgbbyoimpybpmxmyrddbxuhherfeclBitPackLib.huff b/src/utils/__TEMP__fvsgbbyoimpybpmxmyrddbxuhherfeclBitPackLib.huff new file mode 100644 index 00000000..01993e90 --- /dev/null +++ b/src/utils/__TEMP__fvsgbbyoimpybpmxmyrddbxuhherfeclBitPackLib.huff @@ -0,0 +1,104 @@ +#define function packValue(bytes32, uint256, uint256, uint256) pure returns (bytes32) +#define function unpackValueFromRight(bytes32, uint256) pure returns (uint256) +#define function unpackValueFromLeft(bytes32, uint256) pure returns (uint256) +#define function unpackValueFromCenter(bytes32, uint256, uint256) pure returns (uint256) + +#define macro PACK_VALUE_WRAPPER() = takes (0) returns (0) { + 0x04 calldataload // [word] + 0x24 calldataload // [value, word] + 0x44 calldataload // [index, value, word] + 0x64 calldataload // [length, index, value, word] + PACK_VALUE() // [new_word] + 0x00 mstore // [] + 0x20 0x00 return +} + +#define macro UNPACK_FROM_RIGHT_WRAPPER() = takes (0) returns (0) { + 0x04 calldataload // [word] + 0x24 calldataload // [length, word] + UNPACK_FROM_RIGHT() // [value] + 0x00 mstore // [] + 0x20 0x00 return +} + +#define macro UNPACK_FROM_LEFT_WRAPPER() = takes (0) returns (0) { + 0x04 calldataload // [word] + 0x24 calldataload // [length, word] + UNPACK_FROM_LEFT() // [value] + 0x00 mstore // [] + 0x20 0x00 return +} + +#define macro UNPACK_FROM_CENTER_WRAPPER() = takes (0) returns (0) { + 0x04 calldataload // [word] + 0x24 calldataload // [length, word] + 0x44 calldataload // [length, index, word] + UNPACK_FROM_CENTER() // [value] + 0x00 mstore // [] + 0x20 0x00 return +} + +#define macro MAIN() = takes (0) returns (0) { + // Identify which function is being called using the 4 byte function signature + pc calldataload 0xE0 shr + + dup1 __FUNC_SIG(packValue) eq packValue jumpi + dup1 __FUNC_SIG(unpackValueFromRight) eq unpackValueFromRight jumpi + dup1 __FUNC_SIG(unpackValueFromLeft) eq unpackValueFromLeft jumpi + dup1 __FUNC_SIG(unpackValueFromCenter) eq unpackValueFromCenter jumpi + + 0x00 0x00 revert + + packValue: + PACK_VALUE_WRAPPER() + unpackValueFromRight: + UNPACK_FROM_RIGHT_WRAPPER() + unpackValueFromLeft: + UNPACK_FROM_LEFT_WRAPPER() + unpackValueFromCenter: + UNPACK_FROM_CENTER_WRAPPER() +} + +/// @title BitPackLib +/// @notice SPDX-License-Identifier: MIT +/// @author kadenzipfel +/// @notice Efficient bit packing library + +#define constant MAX = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + +/// @notice Packs value of given length at index of given word +/// @dev Assumes index < 256 - length +#define macro PACK_VALUE() = takes (4) returns (1) { + // Input stack: // [length, index, value, word] + 0x100 sub sub // [shift, value, word] + shl or // [new_word] +} + +/// @notice Unpacks value of given length from right of word +/// @dev word & (~0 >> (256 - length)) +#define macro UNPACK_FROM_RIGHT() = takes (2) returns (1) { + // Input stack: // [length, word] + [MAX] // [not(0), length, word] + swap1 0x100 sub // [offset, not(0), word] + shr and // [value] +} + +/// @notice Unpacks value of given length from left of word +/// @dev word >> (256 - length) +#define macro UNPACK_FROM_LEFT() = takes (2) returns (1) { + // Input stack: // [length, word] + 0x100 sub // [shift, word] + shr // [value] +} + +/// @notice Unpacks value of given length from index of word +/// @dev Assumes index < 256 - length +/// (word & ((~0 >> 256 - length) << (256 - length - index))) >> (256 - length - index) +#define macro UNPACK_FROM_CENTER() = takes (3) returns (1) { + // Input stack: // [length, index, word] + 0x100 sub // [256 - length, index, word] + swap1 dup2 sub // [256 - length - index, 256 - length, word] + [MAX] swap1 swap2 shr // [~0 >> 256 - length, 256 - length - index, word] + dup2 shl swap1 swap2 and // [(word & ((~0 >> 256 - length) << (256 - length - index))), 256 - length - index] + swap1 shr // [value] +} diff --git a/src/utils/__TEMP__gbfutonvmuwvpsgnhyhrztoimrzkyqskTSOwnable.huff b/src/utils/__TEMP__gbfutonvmuwvpsgnhyhrztoimrzkyqskTSOwnable.huff new file mode 100644 index 00000000..ec480907 --- /dev/null +++ b/src/utils/__TEMP__gbfutonvmuwvpsgnhyhrztoimrzkyqskTSOwnable.huff @@ -0,0 +1,172 @@ +/// SPDX-License-Identifier: MIT + +#define macro CONSTRUCTOR() = takes (0) returns (0) { + TSOWNABLE_CONSTRUCTOR() +} + +#define macro MAIN() = takes (0) returns (0) { + pc calldataload 0xe0 shr // [sig] + TSOWNABLE_MAIN() // [sig] + 0x00 dup1 revert // [] +} + +/// @title TSOwnable +/// @notice SPDX-License-Identifier: MIT +/// @author merkleplant (modified by @devtooligan) +/// @author asnared +/// @notice An Ownable Implementation using Two-Step Transfer Pattern + +#include "./Address.huff" +#include "./CommonErrors.huff" +#include "../auth/NonPayable.huff" + +// External Interface + +/// @notice Returns the current owner address. +#define function owner() view returns (address) + +/// @notice Returns the current pending owner address. +#define function pendingOwner() view returns (address) + +/// @notice Sets the pending owner address. +/// @dev Only callable by owner. +#define function setPendingOwner(address) nonpayable returns () + +/// @notice Accepts the ownership. +/// @dev Only callable by pending owner. +#define function acceptOwnership() nonpayable returns () + +/// @notice Emitted when new owner set. +#define event NewOwner(address, address) + +/// @notice Emitted when new pending owner set. +#define event NewPendingOwner(address, address) + +// Storage + +/// @notice Owner Storage Slot +#define constant OWNER_SLOT = FREE_STORAGE_POINTER() + +/// @notice Pending Owner Storage Slot +#define constant PENDING_OWNER_SLOT = FREE_STORAGE_POINTER() + +/// @notice Inner TSOwnable Constructor +#define macro TSOWNABLE_CONSTRUCTOR() = takes (0) returns (0) { + // Store msg.sender as owner + caller [OWNER_SLOT] sstore // [] +} + +/// @notice Only Owner Modifier +#define macro ONLY_OWNER_MODIFIER() = takes (0) returns (0) { + [OWNER_SLOT] sload // [owner] + caller eq authed jumpi // [] + ONLY_OWNER(0x00) // [] + authed: // [] +} + +/// @notice Only Pending Owner Modifier +#define macro ONLY_PENDING_OWNER_MODIFIER() = takes (0) returns (0) { + [PENDING_OWNER_SLOT] sload // [pending_owner] + caller eq // [msg.sender == pending_owner] + authed jumpi // [] + ONLY_PENDING_OWNER(0x00) // [] + authed: // [] +} + +// Mutating Functions + +/// @notice Set Pending Owner +/// @param newOwner The address of the new pending owner +#define macro OWNABLE_SET_PENDING_OWNER() = takes (0) returns (0) { + NON_PAYABLE() // [] + ONLY_OWNER_MODIFIER() // [] + + // Read argument and mask to address + 0x04 calldataload MASK_ADDRESS() // [newOwner] + + // Revert if address equals owner + dup1 caller // [owner, newOwner, newOwner] + eq iszero set jumpi // [newOwner] + ALREADY_OWNER(0x00) // [] + set: // [newOwner] + + // Duplicate address on stack + dup1 // [newOwner, newOwner] + + // Emit NewPendingOwner event + [OWNER_SLOT] sload // [owner, newOwner, newOwner] + __EVENT_HASH(NewPendingOwner) 0x00 0x00 // [offset, size, sig, owner, newOwner, newOwner] + log3 // [newOwner] + + // Store address as pending owner + [PENDING_OWNER_SLOT] sstore // [] + + // Stop execution + stop +} + +/// @notice Accept Ownership +/// @notice Allows the pending owner to become the owner +#define macro OWNABLE_ACCEPT_OWNERSHIP() = takes (0) returns (0) { + NON_PAYABLE() // [] + ONLY_PENDING_OWNER_MODIFIER() // [] + + // Emit NewOwner event + caller [OWNER_SLOT] sload // [owner, pending_owner] + __EVENT_HASH(NewOwner) 0x00 0x00 // [offset, size, sig, owner, pending_owner] + log3 // [] + + // Store msg.sender as owner + caller [OWNER_SLOT] sstore // [] + + // Clear pending owner + 0x00 [PENDING_OWNER_SLOT] sstore // [] + + // Stop execution + stop +} + +// View Functions + +/// @notice Get Owner +/// @notice Returns the current owner +#define macro OWNABLE_GET_OWNER() = takes (0) returns (0) { + NON_PAYABLE() // [] + [OWNER_SLOT] sload // [owner] + 0x00 mstore // [] + 0x20 0x00 return // [] +} + +/// @notice Get Pending Owner +/// @notice Returns the current pending owner +#define macro OWNABLE_GET_PENDING_OWNER() = takes (0) returns (0) { + NON_PAYABLE() // [] + [PENDING_OWNER_SLOT] sload // [pending_owner] + 0x00 mstore // [] + 0x20 0x00 return // [] +} + +// Function Dispatching +#define macro TSOWNABLE_MAIN() = takes (1) returns (1) { + // Input stack: [sig] + // Output stack: [sig] + + dup1 __FUNC_SIG(setPendingOwner) eq set_pending_owner jumpi + dup1 __FUNC_SIG(acceptOwnership) eq accept_ownership jumpi + dup1 __FUNC_SIG(owner) eq get_owner jumpi + dup1 __FUNC_SIG(pendingOwner) eq get_pending_owner jumpi + + // Bubble up to the parent macro + no_match jump + + set_pending_owner: + OWNABLE_SET_PENDING_OWNER() + accept_ownership: + OWNABLE_ACCEPT_OWNERSHIP() + get_owner: + OWNABLE_GET_OWNER() + get_pending_owner: + OWNABLE_GET_PENDING_OWNER() + + no_match: +} diff --git a/src/utils/__TEMP__gzlramplmuvmnsgrxrurevmmugyklixkEthers.huff b/src/utils/__TEMP__gzlramplmuvmnsgrxrurevmmugyklixkEthers.huff new file mode 100644 index 00000000..12fda5c0 --- /dev/null +++ b/src/utils/__TEMP__gzlramplmuvmnsgrxrurevmmugyklixkEthers.huff @@ -0,0 +1,47 @@ + +// Receives ether +#define function isPayable() payable returns (uint256) +#define function nonPayable() nonpayable returns (uint256) + +// Match the function selector +#define macro MAIN() = takes (0) returns (0) { + pc calldataload 0xe0 shr + + dup1 __FUNC_SIG(isPayable) eq payable_jump jumpi + dup1 __FUNC_SIG(nonPayable) eq non_payable_jump jumpi + + // Revert if no function selectors match + reverts: + 0x00 dup1 revert + + non_payable_jump: + callvalue iszero iszero reverts jumpi + payable_jump: + balance 0x00 mstore + 0x20 0x00 return +} + +/// @title Ethers +/// @notice SPDX-License-Identifier: MIT +/// @author asnared +/// @notice Utilities for working with ether at a low level + +/// @notice Sends an amount of ether to the specified [amount, address] +#define macro SEND_ETH() = takes (2) returns (1) { + // Input Stack: [amount, address] + + // Send the ether + 0x00 // [0, amount, address] + dup1 // [0, 0, amount, address] + dup1 // [0, 0, 0, amount, address] + dup1 // [0, 0, 0, 0, amount, address] + dup5 // [amount, 0, 0, 0, 0, amount, address] + dup7 // [address, amount, 0, 0, 0, 0, amount] + gas // [gas, address, amount, 0, 0, 0, 0, amount, address] + call // [success, amount, address] + + // Clean the stack + swap2 // [address, amount, success] + pop // [success, address] + pop // [success] +} \ No newline at end of file diff --git a/src/utils/__TEMP__hkejoojmditrgmsogdgtpmxmtwqmpdocReentrancyGuard.huff b/src/utils/__TEMP__hkejoojmditrgmsogdgtpmxmtwqmpdocReentrancyGuard.huff new file mode 100644 index 00000000..33534b5b --- /dev/null +++ b/src/utils/__TEMP__hkejoojmditrgmsogdgtpmxmtwqmpdocReentrancyGuard.huff @@ -0,0 +1,127 @@ + +#define function state() view returns (uint256) +#define function lock() nonpayable returns () +#define function unlock() nonpayable returns () + +#define macro LOCK_WRAPPER() = takes (0) returns (0) { + LOCK() + stop +} + +#define macro UNLOCK_WRAPPER() = takes (0) returns (0) { + UNLOCK() + stop +} + +#define macro GET_STATE() = takes (0) returns (0) { + [LOCKED_SLOT] sload // [LOCKED] + 0x00 mstore // [] + 0x20 0x00 return // [] +} + +#define macro MAIN() = takes (0) returns (0) { + pc calldataload 0xE0 shr // [selector] + + dup1 __FUNC_SIG(state) eq state_jump jumpi + dup1 __FUNC_SIG(lock) eq lock_jump jumpi + dup1 __FUNC_SIG(unlock) eq unlock_jump jumpi + + DISPATCH_ERROR(0x00) + + state_jump: + GET_STATE() + + lock_jump: + LOCK_WRAPPER() + + unlock_jump: + UNLOCK_WRAPPER() +} + +/// @title Reentrancy Guard +/// @notice SPDX-License-Identifier: MIT +/// @author rayquaza7 +/// @notice Gas optimized reentrancy guard for smart contracts. +/// @notice Adapted from Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/ReentrancyGuard.sol) + +#include "./CommonErrors.huff" + +// Interface +#define function lock() nonpayable returns () +#define function unlock() nonpayable returns () + +// Constants +#define constant LOCKED_SLOT = FREE_STORAGE_POINTER() +#define constant _UNLOCKED = 0x01 +#define constant _LOCKED = 0x02 + +/// @title Lock +/// @notice Locks the contract to prevent reentrancy +#define fn LOCK() = takes (0) returns (0) { + [_LOCKED] // [0x02] + dup1 // [0x02, 0x02] + [LOCKED_SLOT] // [locked_slot, 0x02, 0x02] + sload // [locked_slot_value, 0x02, 0x02] + lt // [locked_slot_value < 0x02, 0x02] + lock jumpi + + // Otherwise revert with re-entrancy + REENTRANCY(0x00) + + lock: + [LOCKED_SLOT] sstore +} + +/// @title Unlock +/// @notice Unlocks the contract +#define fn UNLOCK() = takes (0) returns (0) { + [_UNLOCKED] [LOCKED_SLOT] sstore +} + +#define macro REENTRANCY_GUARD_MAIN() = takes (0) returns (0) { + pc calldataload 0xE0 shr + + dup1 __FUNC_SIG(lock) eq lock_jump jumpi + dup1 __FUNC_SIG(unlock) eq unlock_jump jumpi + + reentrancy_sig_no_match_found jump + + lock_jump: + LOCK() + unlock_jump: + UNLOCK() + + reentrancy_sig_no_match_found: +} + +/// @notice Test Unlocking +#define test TEST_LOCK() = takes (0) returns (0) { + // Make sure our slot is set to the UNLOCKED state + UNLOCK() + + // Lock + LOCK() + [LOCKED_SLOT] sload + + // We expect the locked slot to be set to 2 - the LOCKED state + 0x02 eq succeed jumpi + 0x00 dup1 revert + + succeed: +} + +/// @notice Test Unlocking +#define test TEST_UNLOCK() = takes (0) returns (0) { + // Make sure our slot is set to the LOCKED state + LOCK() + + // Unlock + UNLOCK() + [LOCKED_SLOT] sload + + // We expect the locked slot to be set to 1 - the UNLOCKED state + 0x01 eq succeed jumpi + 0x00 dup1 revert + + succeed: +} \ No newline at end of file diff --git a/src/utils/__TEMP__hutfgjhkcylvhdduoakglqjyfagmmbgbJumpTableUtil.huff b/src/utils/__TEMP__hutfgjhkcylvhdduoakglqjyfagmmbgbJumpTableUtil.huff new file mode 100644 index 00000000..b42ce920 --- /dev/null +++ b/src/utils/__TEMP__hutfgjhkcylvhdduoakglqjyfagmmbgbJumpTableUtil.huff @@ -0,0 +1,149 @@ +#define function getJumpdestMem(uint256) view returns (uint256) +#define function getJumpdestStack(uint256) view returns (uint256) +#define function getJumpdestMemPacked(uint256) view returns (uint256) +#define function getJumpdestStackPacked(uint256) view returns (uint256) + +#define jumptable TEST_TABLE { + test_label_a test_label_b test_label_c test_label_d +} + +#define jumptable__packed TEST_TABLE_PACKED { + test_label_a test_label_b test_label_c test_label_d +} + +#define macro GET_JUMPDEST_MEM_WRAPPER() = takes (0) returns (0) { + __tablestart(TEST_TABLE) // [table_start] + 0x04 calldataload // [n, table_start] + + // Load a jumpdest inside of `TEST_TABLE` at index `n` into + // memory at 0x00. + LOAD_FROM_JT(0x00) // [] + 0x20 0x00 return +} + +#define macro GET_JUMPDEST_STACK_WRAPPER() = takes (0) returns (0) { + __tablestart(TEST_TABLE) // [table_start] + 0x04 calldataload // [n, table_start] + RETRIEVE_FROM_JT() // [jumpdest_pc] + + // Store our jumpdest_pc in memory & return it + 0x00 mstore // [] + 0x20 0x00 return +} + +#define macro GET_JUMPDEST_MEM_PACKED_WRAPPER() = takes (0) returns (0) { + __tablestart(TEST_TABLE_PACKED) // [table_start] + 0x04 calldataload // [n, table_start] + + // Store the retrieved jumpdest at 0x00 in memory. + // Since `LOAD_FROM_PACKED_JT` only retrieves 2 bytes + // from the contract's code in the `codecopy` op, we + // need to pass our desired memory pointer + 0x1e (30 bytes) + LOAD_FROM_PACKED_JT(0x1e) // [] + 0x20 0x00 return +} + +#define macro GET_JUMPDEST_STACK_PACKED_WRAPPER() = takes (0) returns (0) { + __tablestart(TEST_TABLE_PACKED) // [table_start] + 0x04 calldataload // [n, table_start] + RETRIEVE_FROM_PACKED_JT() // [jumpdest_pc] + + // Store our jumpdest_pc in memory & return it + 0x00 mstore // [] + 0x20 0x00 return +} + +#define macro MAIN() = takes (0) returns (0) { + pc calldataload 0xE0 shr + dup1 __FUNC_SIG(getJumpdestMem) eq get_jumpdest_mem jumpi + dup1 __FUNC_SIG(getJumpdestStack) eq get_jumpdest_stack jumpi + dup1 __FUNC_SIG(getJumpdestMemPacked) eq get_jumpdest_mem_packed jumpi + dup1 __FUNC_SIG(getJumpdestStackPacked) eq get_jumpdest_stack_packed jumpi + + // Revert if no function signature matched + test_label_d jump + + get_jumpdest_mem: + GET_JUMPDEST_MEM_WRAPPER() + get_jumpdest_stack: + GET_JUMPDEST_MEM_WRAPPER() + get_jumpdest_mem_packed: + GET_JUMPDEST_MEM_PACKED_WRAPPER() + get_jumpdest_stack_packed: + GET_JUMPDEST_STACK_PACKED_WRAPPER() + + // Test labels included in `TEST_TABLE` + test_label_a: + test_label_b: + test_label_c: + test_label_d: + 0x00 dup1 revert +} + + +/// @title JumpTableUtil +/// @notice SPDX-License-Identifier: MIT +/// @author clabby +/// @notice Utility macros for retrieving jumpdest pcs from jump tables + +/// @notice Loads a jumpdest stored in a jumptable into memory at `mem_ptr` +/// +/// @param mem_ptr The memory location to load the 2 byte jumpdest into +/// @param index The index of the jumpdest within the jumptable +/// @param table_start The offset of the jumptable in the contract's bytecode +#define macro LOAD_FROM_JT(mem_ptr) = takes (2) returns (1) { + // Input stack: [index, table_start] + + 0x05 shl add // [table_start + index * 0x20] + 0x20 swap1 // [table_start + index * 0x20, 0x20] + // [mem_ptr, table_start + index * 0x20, 0x20] + codecopy // [] + + // Return stack: [] +} + +/// @notice Retrieves a jumpdest stored in a jumptable and puts it on the stack +/// +/// @param index The index of the jumpdest within the jumptable +/// @param table_start The offset of the jumptable in the contract's bytecode +#define macro RETRIEVE_FROM_JT() = takes (2) returns (1) { + // Input stack: [index, table_start] + + LOAD_FROM_JT(0x00) // [] + 0x00 mload // [res] + + // Return stack: [res] +} + +/// @notice Loads a jumpdest stored in a packed jumptable into memory at `mem_ptr` +/// @dev This macro only loads 2 bytes from the contract code, so make sure to account +/// for this when passing a `mem_ptr`. I.e., if we want to store the jumpdest pc +/// at offset `x`, we would pass in `x + 0x1e` as the `mem_ptr` argument. +/// +/// @param mem_ptr The memory location to load the 2 byte jumpdest into +/// @param index The index of the jumpdest within the packed jumptable +/// @param table_start The offset of the packed jumptable in the contract's bytecode +#define macro LOAD_FROM_PACKED_JT(mem_ptr) = takes (2) returns (1) { + // Input stack: [index, table_start] + + 0x01 shl add // [table_start + index * 0x02] + 0x02 swap1 // [table_start + index * 0x02, 0x02] + // [mem_ptr, table_start + index * 0x02, 0x02] + codecopy // [] + + // Return stack: [] +} + +/// @notice Retrieves a jumpdest stored in a packed jumptable and puts it on the stack +/// +/// @param index The index of the jumpdest within the packed jumptable +/// @param table_start The offset of the packed jumptable in the contract's bytecode +#define macro RETRIEVE_FROM_PACKED_JT() = takes (2) returns (1) { + // Input stack: [index, table_start] + + LOAD_FROM_PACKED_JT(0x1e) + // [] + 0x00 mload // [res] + + // Return stack: [res] +} diff --git a/src/utils/__TEMP__iuxgytjvcjspqzqpxtbelyxicffhqxfrSSTORE2.huff b/src/utils/__TEMP__iuxgytjvcjspqzqpxtbelyxicffhqxfrSSTORE2.huff new file mode 100644 index 00000000..da214168 --- /dev/null +++ b/src/utils/__TEMP__iuxgytjvcjspqzqpxtbelyxicffhqxfrSSTORE2.huff @@ -0,0 +1,132 @@ + +// #define function read(address, uint256) view returns (bytes memory) +// #define function read(address, uint256, uint256) view returns (bytes memory) +#define function read(address) view returns (bytes memory) +#define function write(bytes memory) nonpayable returns (address) + +#define macro SSTORE2_WRITE_WRAPPER() = takes (0) returns (0) { + SSTORE2_WRITE() // [address] + 0x00 mstore // [] + 0x20 0x00 return // [] +} + +#define macro SSTORE2_READ_WRAPPER() = takes (0) returns (0) { + 0x04 calldataload // [pointer] + SSTORE2_READ() // [data_length_in_memory] + 0x00 return // [] +} + +#define macro SSTORE2_READ_AT_WRAPPER() = takes (0) returns (0) { + 0x24 calldataload // [start] + 0x04 calldataload // [pointer, start] + SSTORE2_READ_AT() // [data_length_in_memory] + 0x00 return // [] +} + +#define macro SSTORE2_READ_BETWEEN_WRAPPER() = takes (0) returns (0) { + 0x44 calldataload // [end] + 0x24 calldataload // [start, end] + 0x04 calldataload // [pointer, start, end] + SSTORE2_READ_BETWEEN() // [data_length_in_memory] + 0x00 return // [] +} + +#define macro MAIN() = takes (0) returns (0) { + pc calldataload 0xE0 shr // [selector] + + dup1 __FUNC_SIG(write) eq write_jump jumpi + dup1 __FUNC_SIG(read) eq read_jump jumpi + dup1 __FUNC_SIG("read(address,uint256)") eq read_at_jump jumpi + dup1 __FUNC_SIG("read(address,uint256,uint256)") eq read_between_jump jumpi + + 0x00 dup1 revert + + write_jump: + SSTORE2_WRITE_WRAPPER() + + read_jump: + SSTORE2_READ_WRAPPER() + + read_at_jump: + SSTORE2_READ_AT_WRAPPER() + + read_between_jump: + SSTORE2_READ_BETWEEN_WRAPPER() +} + +/// @title SSTORE2 +/// @notice SPDX-License-Identifier: MIT +/// @author asnared +/// @notice Faster & cheaper contract key-value storage for Ethereum Contracts +/// @notice Adapted from 0xsequence/sstore2 (https://github.com/0xsequence/sstore2) + +#include "./Bytecode.huff" +#include "./CommonErrors.huff" + +#define constant TYPE_UINT_256_MAX = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + +/// @notice Stores `_data` and returns `pointer` as key for later retrieval +/// @dev The pointer is a contract address with `_data` as code +/// @param {_data} [bytes memory] to be written +/// @return pointer Pointer to the written `_data` +#define macro SSTORE2_WRITE() = takes (0) returns (1) { + // Load the data memory pointer + 0x04 calldataload // [&_data] + dup1 0x04 add calldataload swap1 // [&_data, _data.length] + + // Create the contract creation code + CREATION_CODE_FOR() // [&_data, _data.length] + + // Deploy the contract + swap1 // [_data.length, &_data] + 0x0f add // [size, &_data] + 0x00 // [offset, size, &_data] + 0x00 // [value, offset, size, &_data] + create // [address, &_data] + + // Check that the address is non-zero + dup1 iszero iszero success jumpi // [address, &_data] + CREATE_FAILED(0x00) + success: + + // Clean the stack and return the address + swap1 pop // [address] +} + +/// @notice Reads the contents of the `_pointer` code as data, skips the first byte +/// @dev The function is intended for reading pointers generated by `write` +/// @param _pointer to be read +/// @return data read from `_pointer` contract +#define macro SSTORE2_READ() = takes (1) returns (1) { + // Input Stack: [_pointer] + // We start at 1 because the first byte are zeros to prevent the contract from being called + 0x01 // [_start, _pointer] + [TYPE_UINT_256_MAX] // [_end, _start, _pointer] + swap2 // [_pointer, _start, _end] + CODE_AT() // [code] +} + +/// @notice Reads the contents of the `_pointer` code as data, skips the first byte +/// @dev The function is intended for reading pointers generated by `write` +/// @param _pointer to be read +/// @param _start number of bytes to skip +/// @return data read from `_pointer` contract +#define macro SSTORE2_READ_AT() = takes (2) returns (1) { + // Input Stack: [_pointer, _start] + swap1 // [_start, _pointer] + [TYPE_UINT_256_MAX] // [_end, _start, _pointer] + swap2 // [_pointer, _start, _end] + CODE_AT() // [code] +} + +/// @notice Reads the contents of the `_pointer` code as data, skips the first byte +/// @dev The function is intended for reading pointers generated by `write` +/// @param _pointer to be read +/// @param _start number of bytes to skip +/// @param _end index before which to end extraction +/// @return data read from `_pointer` contract +#define macro SSTORE2_READ_BETWEEN() = takes (3) returns (1) { + // Input Stack: [_pointer, _start, _end] + CODE_AT() // [code] +} + diff --git a/src/utils/__TEMP__kfkjwomkxvqpeatpkwmzsmvjaneohelmRefunded.huff b/src/utils/__TEMP__kfkjwomkxvqpeatpkwmzsmvjaneohelmRefunded.huff new file mode 100644 index 00000000..6dde1042 --- /dev/null +++ b/src/utils/__TEMP__kfkjwomkxvqpeatpkwmzsmvjaneohelmRefunded.huff @@ -0,0 +1,97 @@ + +#define function refundedCall() payable returns () +#define function nonRefundedCall() payable returns () + +#define event NonRefundedCall(address) + +#define macro MAIN() = takes (0) returns (0) { + pc calldataload 0xe0 shr + + dup1 __FUNC_SIG(refundedCall) eq refunded_call jumpi + dup1 __FUNC_SIG(nonRefundedCall) eq non_refunded_call jumpi + + 0x00 dup1 revert + + refunded_logic: + caller __EVENT_HASH(NonRefundedCall) 0x00 0x00 log2 + __Refund_Return_Dest jump + + refunded_call: + REFUNDED(refunded_logic) + stop + non_refunded_call: + caller __EVENT_HASH(NonRefundedCall) 0x00 0x00 log2 + stop +} + +/// @title Refunded +/// @notice SPDX-License-Identifier: MIT +/// @author asnared +/// @notice Efficient gas refunds distributed through a modifier +/// @notice Adapted from Zolidity (https://github.com/z0r0z/zolidity/blob/main/src/utils/Refunded.sol) + +#include "./Errors.huff" +#include "./ReentrancyGuard.huff" + +/// @notice The base cost of refunding +#define constant BASE_COST = 0x6359 // 25433 + +/// @notice The maximum amount of gas that can be refunded +#define constant GAS_PRICE_MAX = 0x9502F9000 // 4e10 + +// Refunded custom errors +#define constant MAX_GAS_ERROR = 0x4d41585f47415300000000000000000000000000000000000000000000000000 +#define constant MAX_GAS_LENGTH = 0x07 + +/// @notice Refunds contract calls up to a maximum of 4e10 gas +/// @notice Modified functions over 21k gas benefit most from a refund +#define macro REFUNDED(dest) = takes (0) returns (0) { + // Get the starting amount of gas + gas // [gasLeft] + + // Prevent Reentrancy + LOCK() // [gasLeft] + + basefee [GAS_PRICE_MAX] add // [currMaxGas, gasLeft] + gasprice gt iszero // [!(gasPrice > currMaxGas), gasLeft] + __Safe_Gas_Refund__j jumpi // [gasLeft] + MAX_GAS(0x00) + + __Safe_Gas_Refund__j: + + // The below attempts to mimic `_;` using a jump + // NOTE: This must jump back to `__Refund_Return_Dest` to complete the refund + jump + __Refund_Return_Dest: + + // Calculate refund amount + gas swap1 sub // [gasUsed] + [BASE_COST] add // [gasUsed + BASE_COST] + gasprice mul // [(gasUsed + BASE_COST) * gasPrice] + + // Refund the gas to origin + 0x00 // [retOffset, value] + 0x00 // [argSize, retOffset, value] + 0x00 // [argOffset, argSize, retOffset, value] + 0x00 // [retSize, argOffset, argSize, retOffset, value] + swap4 // [value, argOffset, argSize, retOffset, retSize] + origin // [to, value, argOffset, argSize, retOffset, retSize] + gas // [gas, to, value, argOffset, argSize, retOffset, retSize] + call + iszero iszero __Refund_Successful__j jumpi + 0x00 dup1 revert + + // The refund was successful! + __Refund_Successful__j: + + // Finally, unlock the guard + UNLOCK() +} + +/// @notice Reverts with an "MAX_GAS" message if the condition is false +#define macro MAX_GAS(condition) = takes (0) returns (0) { + [MAX_GAS_ERROR] // ["MAX_GAS"] + [MAX_GAS_LENGTH] // [7 (length), "MAX_GAS"] + // [condition, 7 (length), "MAX_GAS"] + REQUIRE() // [] +} \ No newline at end of file diff --git a/src/utils/__TEMP__kkfsbfpunncyiouwtmltswyzljambbxxShuffling.huff b/src/utils/__TEMP__kkfsbfpunncyiouwtmltswyzljambbxxShuffling.huff new file mode 100644 index 00000000..74d30ae0 --- /dev/null +++ b/src/utils/__TEMP__kkfsbfpunncyiouwtmltswyzljambbxxShuffling.huff @@ -0,0 +1,68 @@ +#define function oneWayShuffle(bytes32 seed, uint256 index, uint256 count, uint256 rounds) view returns (uint256) + +#define macro SHUFFLE_WRAPPER() = takes (0) returns (0) { + 0x64 calldataload // [rounds] + 0x44 calldataload // [count, rounds] + 0x24 calldataload // [index, count, rounds] + 0x04 calldataload // [seed, index, count, rounds] + MECHS__ONE_WAY_SHUFFLE(0x60, 0x80) // [index'] + 0x00 mstore 0x20 0x00 return // [] +} + +#define macro MAIN() = takes (0) returns (0) { + pc calldataload 0xE0 shr // [selector] + + dup1 __FUNC_SIG(oneWayShuffle) eq shuffle jumpi + + 0x00 dup1 revert + + shuffle: + SHUFFLE_WRAPPER() +} + + +/// @title Shuffling +/// @notice SPDX-License-Identifier: MIT +/// @author Philogy +/// @author asnared +/// @notice Refactored algorithms for shuffling and other bitwise algorithms. +/// @notice Adapted from Ethereum Consensus Specs (https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#compute_shuffled_index) + +#include "./Address.huff" +#include "./Ternary.huff" + +#include "../math/Math.huff" + +// Constants +#define constant POS_MASK = 0xffffffff00 + +/// @notice Shuffling Algorithm +#define macro MECHS__ONE_WAY_SHUFFLE(mem1, mem2) = takes (4) returns (1) { + // Input Stack: [seed, index, index_count, iters] + // Output Stack: [index'] + + __Mechs__shuffleContinue: // [seed, index, index_count, iters] + mstore // [index, index_count, iters] + 0x20 sha3 // [seed', index, index_count, iters] + dup3 dup1 // [index_count, index_count, seed' index, index_count, iters] + dup3 mod // [pivot, index_count, seed', index, index_count, iters] + dup4 dup3 // [index_count, index, pivot, index_count, seed', index, index_count, iters] + sub add mod // [flip, seed', index, index_count, iters] + dup3 dup2 MAX() // [position, flip, seed', index, index_count, iters] + dup1 [POS_MASK] and // [masked_position, position, flip, seed', index, index_count, iters] + mstore // [position, flip, seed', index, index_count, iters] + 0x40 sha3 // [rand2, position, flip, seed', index, index_count, iters] + swap1 0xff and shr // [rand_bit_unmasked, flip, seed', index, index_count, iters] + 0x1 and // [rand_bit, flip, seed', index, index_count, iters] + swap2 swap3 swap2 // [rand_bit, flip, index, seed', index_count, iters] + NOT_TERNARY() // [index', seed', index_count, iters] + swap1 swap3 // [iters, index', index_count, seed'] + UNSAFE_SUB() swap3 // [seed', index', index_count, iters'] + + // Continue if iters > 0 + dup4 __Mechs__shuffleContinue jumpi + + // Return the index + pop swap2 pop pop // [index'] +} + diff --git a/src/utils/__TEMP__ldwwbkwihqrpqdglcwrdylrneycegnebReentrancyGuard.huff b/src/utils/__TEMP__ldwwbkwihqrpqdglcwrdylrneycegnebReentrancyGuard.huff new file mode 100644 index 00000000..33534b5b --- /dev/null +++ b/src/utils/__TEMP__ldwwbkwihqrpqdglcwrdylrneycegnebReentrancyGuard.huff @@ -0,0 +1,127 @@ + +#define function state() view returns (uint256) +#define function lock() nonpayable returns () +#define function unlock() nonpayable returns () + +#define macro LOCK_WRAPPER() = takes (0) returns (0) { + LOCK() + stop +} + +#define macro UNLOCK_WRAPPER() = takes (0) returns (0) { + UNLOCK() + stop +} + +#define macro GET_STATE() = takes (0) returns (0) { + [LOCKED_SLOT] sload // [LOCKED] + 0x00 mstore // [] + 0x20 0x00 return // [] +} + +#define macro MAIN() = takes (0) returns (0) { + pc calldataload 0xE0 shr // [selector] + + dup1 __FUNC_SIG(state) eq state_jump jumpi + dup1 __FUNC_SIG(lock) eq lock_jump jumpi + dup1 __FUNC_SIG(unlock) eq unlock_jump jumpi + + DISPATCH_ERROR(0x00) + + state_jump: + GET_STATE() + + lock_jump: + LOCK_WRAPPER() + + unlock_jump: + UNLOCK_WRAPPER() +} + +/// @title Reentrancy Guard +/// @notice SPDX-License-Identifier: MIT +/// @author rayquaza7 +/// @notice Gas optimized reentrancy guard for smart contracts. +/// @notice Adapted from Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/ReentrancyGuard.sol) + +#include "./CommonErrors.huff" + +// Interface +#define function lock() nonpayable returns () +#define function unlock() nonpayable returns () + +// Constants +#define constant LOCKED_SLOT = FREE_STORAGE_POINTER() +#define constant _UNLOCKED = 0x01 +#define constant _LOCKED = 0x02 + +/// @title Lock +/// @notice Locks the contract to prevent reentrancy +#define fn LOCK() = takes (0) returns (0) { + [_LOCKED] // [0x02] + dup1 // [0x02, 0x02] + [LOCKED_SLOT] // [locked_slot, 0x02, 0x02] + sload // [locked_slot_value, 0x02, 0x02] + lt // [locked_slot_value < 0x02, 0x02] + lock jumpi + + // Otherwise revert with re-entrancy + REENTRANCY(0x00) + + lock: + [LOCKED_SLOT] sstore +} + +/// @title Unlock +/// @notice Unlocks the contract +#define fn UNLOCK() = takes (0) returns (0) { + [_UNLOCKED] [LOCKED_SLOT] sstore +} + +#define macro REENTRANCY_GUARD_MAIN() = takes (0) returns (0) { + pc calldataload 0xE0 shr + + dup1 __FUNC_SIG(lock) eq lock_jump jumpi + dup1 __FUNC_SIG(unlock) eq unlock_jump jumpi + + reentrancy_sig_no_match_found jump + + lock_jump: + LOCK() + unlock_jump: + UNLOCK() + + reentrancy_sig_no_match_found: +} + +/// @notice Test Unlocking +#define test TEST_LOCK() = takes (0) returns (0) { + // Make sure our slot is set to the UNLOCKED state + UNLOCK() + + // Lock + LOCK() + [LOCKED_SLOT] sload + + // We expect the locked slot to be set to 2 - the LOCKED state + 0x02 eq succeed jumpi + 0x00 dup1 revert + + succeed: +} + +/// @notice Test Unlocking +#define test TEST_UNLOCK() = takes (0) returns (0) { + // Make sure our slot is set to the LOCKED state + LOCK() + + // Unlock + UNLOCK() + [LOCKED_SLOT] sload + + // We expect the locked slot to be set to 1 - the UNLOCKED state + 0x01 eq succeed jumpi + 0x00 dup1 revert + + succeed: +} \ No newline at end of file diff --git a/src/utils/__TEMP__piwyyoypwjyhbfuzsxxekolsbwxgwxsdSSTORE2.huff b/src/utils/__TEMP__piwyyoypwjyhbfuzsxxekolsbwxgwxsdSSTORE2.huff new file mode 100644 index 00000000..da214168 --- /dev/null +++ b/src/utils/__TEMP__piwyyoypwjyhbfuzsxxekolsbwxgwxsdSSTORE2.huff @@ -0,0 +1,132 @@ + +// #define function read(address, uint256) view returns (bytes memory) +// #define function read(address, uint256, uint256) view returns (bytes memory) +#define function read(address) view returns (bytes memory) +#define function write(bytes memory) nonpayable returns (address) + +#define macro SSTORE2_WRITE_WRAPPER() = takes (0) returns (0) { + SSTORE2_WRITE() // [address] + 0x00 mstore // [] + 0x20 0x00 return // [] +} + +#define macro SSTORE2_READ_WRAPPER() = takes (0) returns (0) { + 0x04 calldataload // [pointer] + SSTORE2_READ() // [data_length_in_memory] + 0x00 return // [] +} + +#define macro SSTORE2_READ_AT_WRAPPER() = takes (0) returns (0) { + 0x24 calldataload // [start] + 0x04 calldataload // [pointer, start] + SSTORE2_READ_AT() // [data_length_in_memory] + 0x00 return // [] +} + +#define macro SSTORE2_READ_BETWEEN_WRAPPER() = takes (0) returns (0) { + 0x44 calldataload // [end] + 0x24 calldataload // [start, end] + 0x04 calldataload // [pointer, start, end] + SSTORE2_READ_BETWEEN() // [data_length_in_memory] + 0x00 return // [] +} + +#define macro MAIN() = takes (0) returns (0) { + pc calldataload 0xE0 shr // [selector] + + dup1 __FUNC_SIG(write) eq write_jump jumpi + dup1 __FUNC_SIG(read) eq read_jump jumpi + dup1 __FUNC_SIG("read(address,uint256)") eq read_at_jump jumpi + dup1 __FUNC_SIG("read(address,uint256,uint256)") eq read_between_jump jumpi + + 0x00 dup1 revert + + write_jump: + SSTORE2_WRITE_WRAPPER() + + read_jump: + SSTORE2_READ_WRAPPER() + + read_at_jump: + SSTORE2_READ_AT_WRAPPER() + + read_between_jump: + SSTORE2_READ_BETWEEN_WRAPPER() +} + +/// @title SSTORE2 +/// @notice SPDX-License-Identifier: MIT +/// @author asnared +/// @notice Faster & cheaper contract key-value storage for Ethereum Contracts +/// @notice Adapted from 0xsequence/sstore2 (https://github.com/0xsequence/sstore2) + +#include "./Bytecode.huff" +#include "./CommonErrors.huff" + +#define constant TYPE_UINT_256_MAX = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + +/// @notice Stores `_data` and returns `pointer` as key for later retrieval +/// @dev The pointer is a contract address with `_data` as code +/// @param {_data} [bytes memory] to be written +/// @return pointer Pointer to the written `_data` +#define macro SSTORE2_WRITE() = takes (0) returns (1) { + // Load the data memory pointer + 0x04 calldataload // [&_data] + dup1 0x04 add calldataload swap1 // [&_data, _data.length] + + // Create the contract creation code + CREATION_CODE_FOR() // [&_data, _data.length] + + // Deploy the contract + swap1 // [_data.length, &_data] + 0x0f add // [size, &_data] + 0x00 // [offset, size, &_data] + 0x00 // [value, offset, size, &_data] + create // [address, &_data] + + // Check that the address is non-zero + dup1 iszero iszero success jumpi // [address, &_data] + CREATE_FAILED(0x00) + success: + + // Clean the stack and return the address + swap1 pop // [address] +} + +/// @notice Reads the contents of the `_pointer` code as data, skips the first byte +/// @dev The function is intended for reading pointers generated by `write` +/// @param _pointer to be read +/// @return data read from `_pointer` contract +#define macro SSTORE2_READ() = takes (1) returns (1) { + // Input Stack: [_pointer] + // We start at 1 because the first byte are zeros to prevent the contract from being called + 0x01 // [_start, _pointer] + [TYPE_UINT_256_MAX] // [_end, _start, _pointer] + swap2 // [_pointer, _start, _end] + CODE_AT() // [code] +} + +/// @notice Reads the contents of the `_pointer` code as data, skips the first byte +/// @dev The function is intended for reading pointers generated by `write` +/// @param _pointer to be read +/// @param _start number of bytes to skip +/// @return data read from `_pointer` contract +#define macro SSTORE2_READ_AT() = takes (2) returns (1) { + // Input Stack: [_pointer, _start] + swap1 // [_start, _pointer] + [TYPE_UINT_256_MAX] // [_end, _start, _pointer] + swap2 // [_pointer, _start, _end] + CODE_AT() // [code] +} + +/// @notice Reads the contents of the `_pointer` code as data, skips the first byte +/// @dev The function is intended for reading pointers generated by `write` +/// @param _pointer to be read +/// @param _start number of bytes to skip +/// @param _end index before which to end extraction +/// @return data read from `_pointer` contract +#define macro SSTORE2_READ_BETWEEN() = takes (3) returns (1) { + // Input Stack: [_pointer, _start, _end] + CODE_AT() // [code] +} + diff --git a/src/utils/__TEMP__ppohrkhyvnxmaxjzqlkackypaopwtytiErrors.huff b/src/utils/__TEMP__ppohrkhyvnxmaxjzqlkackypaopwtytiErrors.huff new file mode 100644 index 00000000..e04e8e5b --- /dev/null +++ b/src/utils/__TEMP__ppohrkhyvnxmaxjzqlkackypaopwtytiErrors.huff @@ -0,0 +1,303 @@ +#define function simulateRequire() pure returns () +#define function simulateAssert() pure returns () +#define function simulateAssertEq() pure returns () +#define function simulateAssertNotEq() pure returns () +#define function simulateAssertMemEq() pure returns () +#define function simulateAssertMemNotEq() pure returns () +#define function simulateAssertStorageEq() nonpayable returns () +#define function simulateAssertStorageNotEq() nonpayable returns () +#define function simulateCompilerPanic() pure returns () +#define function simulateArithmeticOverflow() pure returns () +#define function simulateDivideByZero() pure returns () +#define function simulateInvalidEnumValue() pure returns () +#define function simulateInvalidStorageByteArray() pure returns () +#define function simulateEmptyArrayPop() pure returns () +#define function simulateArrayOutOfBounds() pure returns () +#define function simulateMemoryTooLarge() pure returns () +#define function simulateUninitializedFunctionPointer() pure returns () +#define function simulateBubbleUpIfFailed(address) view returns () + +#define constant REQUIRE_LENGTH = 0x06 +#define constant REQUIRE_STRING = 0x7265766572740000000000000000000000000000000000000000000000000000 + +#define macro MAIN() = takes (0) returns (0) { + pc calldataload 0xe0 shr + dup1 __FUNC_SIG(simulateRequire) eq simulate_require jumpi + dup1 __FUNC_SIG(simulateAssert) eq simulate_assert jumpi + dup1 __FUNC_SIG(simulateAssertEq) eq simulate_assert_eq jumpi + dup1 __FUNC_SIG(simulateAssertNotEq) eq simulate_assert_not_eq jumpi + dup1 __FUNC_SIG(simulateAssertMemEq) eq simulate_assert_mem_eq jumpi + dup1 __FUNC_SIG(simulateAssertMemNotEq) eq simulate_assert_mem_not_eq jumpi + dup1 __FUNC_SIG(simulateAssertStorageEq) eq simulate_assert_storage_eq jumpi + dup1 __FUNC_SIG(simulateAssertStorageNotEq) eq simulate_assert_storage_not_eq jumpi + dup1 __FUNC_SIG(simulateCompilerPanic) eq simulate_compiler_panic jumpi + dup1 __FUNC_SIG(simulateArithmeticOverflow) eq simulateArithmeticOverflow jumpi + dup1 __FUNC_SIG(simulateDivideByZero) eq simulateDivideByZero jumpi + dup1 __FUNC_SIG(simulateInvalidEnumValue) eq simulateInvalidEnumValue jumpi + dup1 __FUNC_SIG(simulateInvalidStorageByteArray) eq simulateInvalidStorageByteArray jumpi + dup1 __FUNC_SIG(simulateEmptyArrayPop) eq simulateEmptyArrayPop jumpi + dup1 __FUNC_SIG(simulateArrayOutOfBounds) eq simulateArrayOutOfBounds jumpi + dup1 __FUNC_SIG(simulateMemoryTooLarge) eq simulateMemoryTooLarge jumpi + dup1 __FUNC_SIG(simulateUninitializedFunctionPointer) eq simulateUninitializedFunctionPointer jumpi + dup1 __FUNC_SIG(simulateBubbleUpIfFailed) eq simulateBubbleUpIfFailed jumpi + + 0x00 0x00 revert + + simulate_require: + [REQUIRE_STRING] // [message] + [REQUIRE_LENGTH] // [message_length, message] + 0x00 // [false, message_length, message] + REQUIRE() // [] + + simulate_assert: + 0x00 // [false] + ASSERT() // [] + + simulate_assert_eq: + 0x01 0x00 // [0x00, 0x01] + ASSERT_EQ() + + simulate_assert_not_eq: + 0x00 0x00 // [0x00, 0x00] + ASSERT_NOT_EQ() + + simulate_assert_mem_eq: + 0x00 dup1 mstore + 0x01 0x20 mstore + ASSERT_MEM_EQ(0x00, 0x20) + + simulate_assert_mem_not_eq: + 0x00 dup1 mstore + 0x00 0x20 mstore + ASSERT_MEM_NOT_EQ(0x00, 0x20) + + simulate_assert_storage_eq: + 0x00 dup1 sstore + 0x01 dup1 sstore + ASSERT_STORAGE_EQ(0x00, 0x01) + + simulate_assert_storage_not_eq: + 0x00 dup1 sstore + 0x00 0x01 sstore + ASSERT_STORAGE_NOT_EQ(0x00, 0x01) + + simulate_compiler_panic: + [COMPILER_PANIC] + do_panic + jump + + simulateArithmeticOverflow: + [ARITHMETIC_OVERFLOW] + do_panic + jump + + simulateDivideByZero: + [DIVIDE_BY_ZERO] + do_panic + jump + + simulateInvalidEnumValue: + [INVALID_ENUM_VALUE] + do_panic + jump + + simulateInvalidStorageByteArray: + [INVALID_STORAGE_BYTE_ARRAY] + do_panic + jump + + simulateEmptyArrayPop: + [EMPTY_ARRAY_POP] + do_panic + jump + + simulateArrayOutOfBounds: + [ARRAY_OUT_OF_BOUNDS] + do_panic + jump + + simulateMemoryTooLarge: + [MEMORY_TOO_LARGE] + do_panic + jump + + simulateUninitializedFunctionPointer: + [UNINITIALIZED_FUNCTION_POINTER] + do_panic + jump + + simulateBubbleUpIfFailed: + 0x00 // [ret_size] + dup1 // [ret_offset, ret_size] + dup1 // [args_size, ret_offset, ret_size] + dup1 // [args_offset, args_size, ret_offst, ret_size] + dup1 // [value, args_offset, args_size, ret_offst, ret_size] + 0x04 // [addr_offset, value, args_offset, args_size, ret_offst, ret_size] + calldataload // [addr, value, args_offset, args_size, ret_offst, ret_size] + gas // [gas, addr, value, args_offset, args_size, ret_offst, ret_size] + call // [success] + BUBBLE_UP_IF_FAILED() // [] + + do_panic: + PANIC() +} + + +/// @title Errors +/// @notice SPDX-License-Identifier: MIT +/// @author jtriley.eth +/// @author clabby +/// @notice Custom error utilities. + +// https://docs.soliditylang.org/en/latest/control-structures.html?highlight=panic#panic-via-assert-and-error-via-require + +// Errors +#define error Error(string) +#define error Panic(uint256) + +// Constants +// Solidity Panic Codes +#define constant COMPILER_PANIC = 0x00 +#define constant ASSERT_FALSE = 0x01 +#define constant ARITHMETIC_OVERFLOW = 0x11 +#define constant DIVIDE_BY_ZERO = 0x12 +#define constant INVALID_ENUM_VALUE = 0x21 +#define constant INVALID_STORAGE_BYTE_ARRAY = 0x22 +#define constant EMPTY_ARRAY_POP = 0x31 +#define constant ARRAY_OUT_OF_BOUNDS = 0x32 +#define constant MEMORY_TOO_LARGE = 0x41 +#define constant UNINITIALIZED_FUNCTION_POINTER = 0x51 + +/* + +Solidity Require. Error `string` MUST be no greater than 32 bytes. + +MEMORY LAYOUT WHEN THROWN +| sig || message offset || message length || message "revert" | +0x08c379a 0000000000000000000000000000000000000000000000000000000000000020 0000000000000000000000000000000000000000000000000000000000000006 7265766572740000000000000000000000000000000000000000000000000000 + +*/ +#define macro REQUIRE() = takes (3) returns (0) { + // takes: // [condition, message_length, message] + do_not_throw // [do_not_throw_jumpdest, condition, message_length, message] + jumpi // [message_length, message] + __ERROR(Error) // [error_sig, , message_length, message] + 0x00 // [mem_ptr, error_sig, message_length, message] + mstore // [message_length, message] + 0x20 // [message_offset, message_length, message] + 0x04 // [message_offset_ptr, message_offset, message_length, message] + mstore // [message_length, message] + 0x24 // [message_length_ptr, message_length, message] + mstore // [message] + 0x44 // [message_ptr, message] + mstore // [] + 0x80 // [size] + 0x00 // [offset, size] + revert // [] + do_not_throw: // [message_length, message] + pop // [message] + pop // [] +} + +/* + +Solidity Panic. + +MEMORY LAYOUT WHEN THROWN +| sig || panic code | +0x4e487b71 0000000000000000000000000000000000000000000000000000000000000001 + +*/ +#define macro PANIC() = takes (1) returns (0) { + // takes: // [panic_code] + __ERROR(Panic) // [panic_sig, panic_code] + 0x00 // [panic_sig_offset, panic_sig, panic_code] + mstore // [panic_code] + 0x04 // [panic_code_offset, panic_code] + mstore // [] + 0x24 // [revert_size] + 0x00 // [revert_offset, revert_size] + revert // [] +} + +/* +Solidity Assert. + +MEMORY LAYOUT WHEN THROWN +| sig || assert failed panic code | +0x4e487b71 0000000000000000000000000000000000000000000000000000000000000001 + +*/ +#define macro ASSERT() = takes (1) returns (0) { + // takes: // [condition] + do_not_panic // [do_not_panic_jumpdest, condition] + jumpi // [] + [ASSERT_FALSE] // [assert_false] + PANIC() // [] + do_not_panic: // [] +} + +// Assert that two stack elements are equal +#define macro ASSERT_EQ() = { + // takes: [a, b] + eq // [a == b] + ASSERT() // [] +} + +// Assert that two stack elements are not equal +#define macro ASSERT_NOT_EQ() = { + // takes: [a, b] + eq iszero // [a != b] + ASSERT() // [] +} + +// Assert that two memory offsets contain equal words +#define macro ASSERT_MEM_EQ(ptr_a, ptr_b) = { + // takes: [] + mload // [b] + mload // [a, b] + eq // [a == b] + ASSERT() // [] +} + +// Assert that two memory offsets do not contain equal words +#define macro ASSERT_MEM_NOT_EQ(ptr_a, ptr_b) = { + // takes: [] + mload // [b] + mload // [a, b] + eq iszero // [a != b] + ASSERT() // [] +} + +// Assert that two storage slots contain equal words +#define macro ASSERT_STORAGE_EQ(slot_a, slot_b) = { + // takes: [] + sload // [b] + sload // [a, b] + eq // [a == b] + ASSERT() // [] +} + +// Assert that two storage slots do not contain equal words +#define macro ASSERT_STORAGE_NOT_EQ(slot_a, slot_b) = { + // takes: [] + sload // [b] + sload // [a, b] + eq iszero // [a != b] + ASSERT() // [] +} + +/* Bubbles up revert data if call failed. Call directly after `call`, `staticcall`, `delegatecall`. */ +#define macro BUBBLE_UP_IF_FAILED() = takes (1) returns (0) { + // takes: // [call_succeeded] + call_succeeded // [call_succeeded_jumpdest, call_succeeded] + jumpi // [] + returndatasize // [returndatasize] + 0x00 // [memory_offset, returndatasize] + returndatasize // [returndatasize, memory_offset, returndatasize] + dup2 // [returndata_offset, returndatasize, memory_offset, returndatasize] + dup3 // [memory_offset, returndata_offset, returndatasize, memory_offset, returndatasize] + returndatacopy // [memory_offset, returndatasize] + revert // [] + call_succeeded: +} diff --git a/src/utils/__TEMP__prdtsuvrwjmqtxbpjcrrcoacbfeiivquShuffling.huff b/src/utils/__TEMP__prdtsuvrwjmqtxbpjcrrcoacbfeiivquShuffling.huff new file mode 100644 index 00000000..74d30ae0 --- /dev/null +++ b/src/utils/__TEMP__prdtsuvrwjmqtxbpjcrrcoacbfeiivquShuffling.huff @@ -0,0 +1,68 @@ +#define function oneWayShuffle(bytes32 seed, uint256 index, uint256 count, uint256 rounds) view returns (uint256) + +#define macro SHUFFLE_WRAPPER() = takes (0) returns (0) { + 0x64 calldataload // [rounds] + 0x44 calldataload // [count, rounds] + 0x24 calldataload // [index, count, rounds] + 0x04 calldataload // [seed, index, count, rounds] + MECHS__ONE_WAY_SHUFFLE(0x60, 0x80) // [index'] + 0x00 mstore 0x20 0x00 return // [] +} + +#define macro MAIN() = takes (0) returns (0) { + pc calldataload 0xE0 shr // [selector] + + dup1 __FUNC_SIG(oneWayShuffle) eq shuffle jumpi + + 0x00 dup1 revert + + shuffle: + SHUFFLE_WRAPPER() +} + + +/// @title Shuffling +/// @notice SPDX-License-Identifier: MIT +/// @author Philogy +/// @author asnared +/// @notice Refactored algorithms for shuffling and other bitwise algorithms. +/// @notice Adapted from Ethereum Consensus Specs (https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#compute_shuffled_index) + +#include "./Address.huff" +#include "./Ternary.huff" + +#include "../math/Math.huff" + +// Constants +#define constant POS_MASK = 0xffffffff00 + +/// @notice Shuffling Algorithm +#define macro MECHS__ONE_WAY_SHUFFLE(mem1, mem2) = takes (4) returns (1) { + // Input Stack: [seed, index, index_count, iters] + // Output Stack: [index'] + + __Mechs__shuffleContinue: // [seed, index, index_count, iters] + mstore // [index, index_count, iters] + 0x20 sha3 // [seed', index, index_count, iters] + dup3 dup1 // [index_count, index_count, seed' index, index_count, iters] + dup3 mod // [pivot, index_count, seed', index, index_count, iters] + dup4 dup3 // [index_count, index, pivot, index_count, seed', index, index_count, iters] + sub add mod // [flip, seed', index, index_count, iters] + dup3 dup2 MAX() // [position, flip, seed', index, index_count, iters] + dup1 [POS_MASK] and // [masked_position, position, flip, seed', index, index_count, iters] + mstore // [position, flip, seed', index, index_count, iters] + 0x40 sha3 // [rand2, position, flip, seed', index, index_count, iters] + swap1 0xff and shr // [rand_bit_unmasked, flip, seed', index, index_count, iters] + 0x1 and // [rand_bit, flip, seed', index, index_count, iters] + swap2 swap3 swap2 // [rand_bit, flip, index, seed', index_count, iters] + NOT_TERNARY() // [index', seed', index_count, iters] + swap1 swap3 // [iters, index', index_count, seed'] + UNSAFE_SUB() swap3 // [seed', index', index_count, iters'] + + // Continue if iters > 0 + dup4 __Mechs__shuffleContinue jumpi + + // Return the index + pop swap2 pop pop // [index'] +} + diff --git a/src/utils/__TEMP__qbvbklotqjimwddbdrttqayfxbbmavfvLibBit.huff b/src/utils/__TEMP__qbvbklotqjimwddbdrttqayfxbbmavfvLibBit.huff new file mode 100644 index 00000000..2ee77790 --- /dev/null +++ b/src/utils/__TEMP__qbvbklotqjimwddbdrttqayfxbbmavfvLibBit.huff @@ -0,0 +1,267 @@ +#define function fls(uint256) pure returns (uint256) +#define function ffs(uint256) pure returns (uint256) +#define function popCount(uint256) pure returns (uint256) +#define function isPowOf2(uint256) pure returns (uint256) + +#define macro FLS_WRAPPER() = { + 0x04 calldataload + FLS() + + 0x00 mstore + 0x20 0x00 return +} + +#define macro FFS_WRAPPER() = { + 0x04 calldataload + FFS() + + 0x00 mstore + 0x20 0x00 return +} + +#define macro POP_COUNT_WRAPPER() = { + 0x04 calldataload + POP_COUNT() + + 0x00 mstore + 0x20 0x00 return +} + +#define macro IS_POW_OF_2_WRAPPER() = { + 0x04 calldataload + IS_POW_OF_2() + + 0x00 mstore + 0x20 0x00 return +} + +#define macro MAIN() = { + pc calldataload 0xE0 shr + dup1 __FUNC_SIG(fls) eq fls jumpi + dup1 __FUNC_SIG(ffs) eq ffs jumpi + dup1 __FUNC_SIG(popCount) eq pop_count jumpi + dup1 __FUNC_SIG(isPowOf2) eq is_pow_of_2 jumpi + + 0x00 dup1 revert + + fls: + FLS_WRAPPER() + ffs: + FFS_WRAPPER() + pop_count: + POP_COUNT_WRAPPER() + is_pow_of_2: + IS_POW_OF_2_WRAPPER() +} + + +/// @title LibBit +/// @notice SPDX-License-Identifier: MIT +/// @author Vectorized +/// @author Solady (https://github.com/Vectorized/solady/blob/main/src/utils/LibBit.sol) +/// @author Inspired by (https://graphics.stanford.edu/~seander/bithacks.html) +/// @author clabby +/// @notice Various bit-twiddling macros. + +#define constant A = 0xffffffffffffffffffffffffffffffff +#define constant B = 0xffffffffffffffff +#define constant C = 0xffffffff + +#define constant FLS_DEBRUIJN = 0x0009010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f +#define constant FFS_DEBRUIJN = 0x00011c021d0e18031e16140f191104081f1b0d17151310071a0c12060b050a09 + +/// @dev Returns the index of the most significant bit of `x`. +/// If `x` is zero, returns 256. +#define macro FLS() = takes (1) returns (1) { + // Input stack: [x] + + dup1 iszero // [x == 0, x] + 0x08 shl // [(x == 0) << 0x08, x] + + dup2 [A] lt // [A < x, r, x] + 0x07 shl // [(A < x) << 0x07, r, x] + or // [r, x] + + dup2 dup2 shr // [x >> r, r, x] + [B] lt // [B < (x >> r), r, x] + 0x06 shl // [(B < (x >> r)) << 0x06, r, x] + or // [r, x] + + dup2 dup2 shr // [x >> r, r, x] + [C] lt // [C < (x >> r), r, x] + 0x05 shl // [(C < (x >> r)) << 0x05, r, x] + or // [r, x] + + // For the remaining 32 bits, use a De Bruijn lookup. + swap1 dup2 shr // [x >> r, r] + dup1 0x01 shr // [(x >> r) >> 0x01, x >> r, r] + or // [x, r] + + dup1 0x02 shr // [x >> 0x02, x, r] + or // [x, r] + + dup1 0x04 shr // [x >> 0x04, x, r] + or // [x, r] + + dup1 0x08 shr // [x >> 0x08, x, r] + or // [x, r] + + dup1 0x10 shr // [x >> 0x10, r] + or // [x, r] + + // Note: This does increase final code size, can shift left by 224 at runtime + // if codesize is more of a concern. + __RIGHTPAD(0x07c4acdd) // [0x07c4acdd (right padded), x, r] + mul // [x * 0x07c4acdd, r] + 0xFB shr // [(x * 0x07c4acdd) >> 0xFB, r] + [FLS_DEBRUIJN] swap1 // [(x * 0x07c4acdd) >> 0xFB, debruijn_lookup, r] + byte // [b, r] + or // [b | r] + + // Return stack: [r] +} + +/// @dev Returns the index of the least significant bit of `x`. +/// If `x` is zero, returns 256. +#define macro FFS() = takes (1) returns (1) { + // Input stack: [x] + + dup1 iszero // [x == 0, x] + 0x08 shl // [(x == 0) << 0x08, x] + + // Isolate the least significant bit. + swap1 dup1 // [x, x, r] + not 0x01 add // [~x + 1, x, r] + and // [x, r] + + swap1 dup2 // [x, r, x] + [A] lt // [A < x, r, x] + 0x07 shl // [(A < x) << 0x07, r, x] + or // [r, x] + + dup2 dup2 shr // [x >> r, r, x] + [B] lt // [B < (x >> r), r, x] + 0x06 shl // [(B < (x >> r)) << 0x06, r, x] + or // [r, x] + + dup2 dup2 shr // [x >> r, r, x] + [C] lt // [C < (x >> r), r, x] + 0x05 shl // [(C < (x >> r)) << 0x05] + or // [r, x] + + // For the remaining 32 bits, use a De Bruijn lookup. + + // Note: This does increase final code size, can shift left by 224 at runtime + // if codesize is more of a concern. + swap1 dup2 shr // [x >> r, r] + __RIGHTPAD(0x077cb531) // [0x077cb531..., x >> r, r] + mul // [(x >> r) * 0x077cb531, r] + 0xFB shr // [(x * 0x077cb531) >> 0xFB, r] + [FFS_DEBRUIJN] swap1 // [(x * 0x077cb531) >> 0xFB, debruijn_lookup, r] + byte // [b, r] + or // [b | r] + + // Return stack: [r] +} + +/// @dev Returns the number of set bits in `x`. +#define macro POP_COUNT() = takes (1) returns (1) { + // Input stack: [x] + + 0x00 not // [max, x] + dup1 dup3 lt // [is_not_max, max, x] + + swap2 // [x, max, is_not_max] + 0x03 dup3 div // [max / 0x03, x, max, is_not_max] + dup2 0x01 shr // [x >> 0x01, max / 0x03, x, max, is_not_max] + and // [(x >> 0x01) & (max / 0x03), x, max, is_not_max] + swap1 sub // [x, max, is_not_max] + + 0x05 dup3 div // [max / 0x05, x, max, is_not_max] + dup1 // [max / 0x05, max / 0x05, x, max, is_not_max] + dup3 0x02 shr // [x >> 0x02, max / 0x05, max / 0x05 x, max, is_not_max] + and // [(x >> 0x02) & (max / 0x05), max / 0x05, x, max, is_not_max] + swap2 // [max / 0x05, x, (x >> 0x02) & (max / 0x05), max, is_not_max] + and add // [x, max, is_not_max] + + 0x11 dup3 div // [max / 0x11, x, max, is_not_max] + swap1 // [x, max / 0x11, max, is_not_max] + dup1 0x04 shr // [x >> 0x04, x, max / 0x11, max, is_not_max] + add and // [x, max, is_not_max] + + swap1 0xFF // [0xFF, max, x, is_not_max] + swap1 div // [max / 0xFF, x, is_not_max] + mul // [(max / 0xFF) * x, is_not_max] + 0xF8 shr // [((max / 0xFF) * x) >> 0xF8, is_not_max] + 0x100 xor // [((max / 0xFF) * x) >> 0xF8) ^ 0x100, is_not_max] + mul // [((((max / 0xFF) * x) >> 0xF8) ^ 0x100) * is_not_max] + 0x100 xor // [(((((max / 0xFF) * x) >> 0xF8) ^ 0x100) * is_not_max) ^ 0x100] + + // Return stack: [c] +} + +/// @dev Returns 1, if the input is a power of 2. +#define macro IS_POW_OF_2() = takes (1) returns (1) { + // Input stack: [x] + + 0x01 // [1,x] + dup2 // [x,1,x] + sub // [x-1,x] + dup2 // [x,x-1,x] + and // [x & x-1,x] + swap1 // [x, x&x-1] + iszero // [x==0, x&x-1] + add // [(x==0) + (x&x-1)] + iszero // [(x==0) + (x&x-1) == 0] + + // Return stack: [c] +} + + +#define test FLS() = { + 0xFF 0x03 shl + FLS() + + 0x0a eq succeed jumpi + 0x00 dup1 revert + + succeed: +} + +#define test FFS() = { + 0xFF 0x03 shl + FFS() + + 0x03 eq succeed jumpi + 0x00 dup1 revert + + succeed: +} + +#define test POP_COUNT() = { + 0x01 dup1 + 0xFF shl or + POP_COUNT() + + 0x02 eq succeed jumpi + 0x00 dup1 revert + + succeed: +} + +#define test IS_POW_OF_2() = { + 0x05 dup1 + IS_POW_OF_2() + + 0x00 eq next jumpi + 0x00 dup1 revert + + next: + 0x08 dup1 + IS_POW_OF_2() + + 0x01 eq succeed jumpi + 0x00 dup1 revert + + succeed: +} \ No newline at end of file diff --git a/src/utils/__TEMP__qfzbthtrligkzrxhdcwizlbkonnnqqiyCalls.huff b/src/utils/__TEMP__qfzbthtrligkzrxhdcwizlbkonnnqqiyCalls.huff new file mode 100644 index 00000000..019625c2 --- /dev/null +++ b/src/utils/__TEMP__qfzbthtrligkzrxhdcwizlbkonnnqqiyCalls.huff @@ -0,0 +1,217 @@ + +#define function callFunc() payable returns () +#define function staticcallFunc() payable returns () +#define function callcodeFunc() payable returns () + +#define macro CALL_WRAPPER() = takes (0) returns (0) { + // Store 0xba5ed in memory + 0xba5ed dup1 0x00 mstore // [0xba5ed] + + // Static Call + CALL(0x01, 0x00, 0x01, 0x00, 0x00, 0x04, 0xFFFFFFFF) // [success, 0xba5ed] + + // Revert if call is unsuccessful + iszero iszero cont jumpi + 0x00 dup1 revert + cont: + + // Load the result + 0x00 mload // [res, 0xba5ed] + + // Compare the results and revert if unequal + eq success jumpi // [] + 0x00 dup1 revert + success: + + stop +} + +#define macro STATICCALL_WRAPPER() = takes (0) returns (0) { + // Store 0xba5ed in memory + 0xba5ed dup1 0x00 mstore // [0xba5ed] + + // Static Call + STATICCALL(0x01, 0x00, 0x01, 0x00, 0x04, 0xFFFFFFFF) // [success, 0xba5ed] + + // Revert if call is unsuccessful + iszero iszero cont jumpi + 0x00 dup1 revert + cont: + + // Load the result + 0x00 mload // [res, 0xba5ed] + + // Compare the results and revert if unequal + eq success jumpi // [] + 0x00 dup1 revert + success: + + stop +} + +#define macro CALLCODE_WRAPPER() = takes (0) returns (0) { + // TODO + + stop +} + +#define macro MAIN() = takes (0) returns (0) { + // Load the function selector + pc calldataload 0xE0 shr // [sig] + + // Match on the function selector + dup1 __FUNC_SIG(callFunc) eq call_jump jumpi // [sig] + dup1 __FUNC_SIG(staticcallFunc) eq staticcall_jump jumpi // [sig] + dup1 __FUNC_SIG(callcodeFunc) eq callcode_jump jumpi // [sig] + + 0x00 dup1 revert + + call_jump: + CALL_WRAPPER() + staticcall_jump: + STATICCALL_WRAPPER() + callcode_jump: + CALLCODE_WRAPPER() +} + + +/// @title Calls +/// @notice SPDX-License-Identifier: MIT +/// @author asnared +/// @author Franfran +/// @notice Calls is a library of utility functions for calling contracts + +/// @notice Calls a contract with the given arguments +/// @notice Returns the success of the call +/// @notice Returndata is left in memory for the caller to handle +/// @param ret_size The size of the return data +/// @param ret_offset The offset in memory to store the return data +/// @param arg_size The size of the arguments +/// @param arg_offset The offset in memory of the arguments +/// @param value The value to send with the call +/// @param to The address to call +/// @param gas The amount of gas to send with the call +#define macro CALL( + ret_size, + ret_offset, + arg_size, + arg_offset, + value, + to, + maxgas +) = takes (0) returns (1) { + // [retSize] + // [retOffset, retSize] + // [argSize, retOffset, retSize] + // [argOffset, argSize, retOffset, retSize] + // [value, argOffset, argSize, retOffset, retSize] + // [to, value, argOffset, argSize, retOffset, retSize] + // [gas, to, value, argOffset, argSize, retOffset, retSize] + call // [success] +} + +/// @notice Staticalls a contract with the given arguments +/// @notice Returns the success of the call +/// @notice Returndata is left in memory for the caller to handle +/// @dev This instructions is equivalent to CALL, except that it does not allow any state modifying instructions or sending ETH in the sub context. +/// @dev The disallowed instructions are CREATE, CREATE2, LOG0, LOG1, LOG2, LOG3, LOG4, SSTORE, SELFDESTRUCT and CALL if the value sent is not 0. +/// @dev If the size of the return data is not known, it can also be retrieved after the call with the instructions RETURNDATASIZE and RETURNDATACOPY (since the Byzantium fork). +/// @param ret_size The size of the return data +/// @param ret_offset The offset in memory to store the return data +/// @param arg_size The size of the arguments +/// @param arg_offset The offset in memory of the arguments +/// @param to The address to call +/// @param gas The amount of gas to send with the call +#define macro STATICCALL( + ret_size, + ret_offset, + arg_size, + arg_offset, + to, + maxgas +) = takes (0) returns (1) { + // [retSize] + // [retOffset, retSize] + // [argSize, retOffset, retSize] + // [argOffset, argSize, retOffset, retSize] + // [to, argOffset, argSize, retOffset, retSize] + // [gas, to, argOffset, argSize, retOffset, retSize] + staticcall // [success] +} + +/// @notice Codecalls a contract with the given arguments +/// @notice Returns the success of the call +/// @notice Returndata is left in memory for the caller to handle +/// @dev Creates a new sub context as if calling itself, but with the code of the given account. +/// @dev In particular the storage remains the same. Note that an account with no code will return success as true. +/// @dev If the size of the return data is not known, it can also be retrieved after the call with the instructions RETURNDATASIZE and RETURNDATACOPY (since the Byzantium fork). +/// @param ret_size The size of the return data +/// @param ret_offset The offset in memory to store the return data +/// @param arg_size The size of the arguments +/// @param arg_offset The offset in memory of the arguments +/// @param value The value to send with the call +/// @param to The address to call +/// @param gas The amount of gas to send with the call +#define macro CALLCODE( + ret_size, + ret_offset, + arg_size, + arg_offset, + value, + to, + maxgas +) = takes (0) returns (1) { + // [retSize] + // [retOffset, retSize] + // [argSize, retOffset, retSize] + // [argOffset, argSize, retOffset, retSize] + // [value, argOffset, argSize, retOffset, retSize] + // [to, argOffset, argSize, retOffset, retSize] + // [gas, to, argOffset, argSize, retOffset, retSize] + callcode // [success] +} + +/// @notice Test call the identity precompile +#define test TEST_CALL() = takes (0) returns (0) { + // Store 0xba5ed in memory + 0xba5ed dup1 0x00 mstore // [0xba5ed] + + // Static Call + CALL(0x01, 0x00, 0x01, 0x00, 0x00, 0x04, 0xFFFFFFFF) // [success, 0xba5ed] + + // Revert if call is unsuccessful + iszero iszero cont jumpi + 0x00 dup1 revert + cont: + + // Load the result + 0x00 mload // [res, 0xba5ed] + + // Compare the results and revert if unequal + eq success jumpi // [] + 0x00 dup1 revert + success: +} + +/// @notice Test staticcall the identity precompile +#define test TEST_STATIC_CALL() = takes (0) returns (0) { + // Store 0xba5ed in memory + 0xba5ed dup1 0x00 mstore // [0xba5ed] + + // Static Call + STATICCALL(0x01, 0x00, 0x01, 0x00, 0x04, 0xFFFFFFFF) // [success, 0xba5ed] + + // Revert if call is unsuccessful + iszero iszero cont jumpi + 0x00 dup1 revert + cont: + + // Load the result + 0x00 mload // [res, 0xba5ed] + + // Compare the results and revert if unequal + eq success jumpi // [] + 0x00 dup1 revert + success: +} + diff --git a/src/utils/__TEMP__rrvaaiimcokotvnwlrlotlmzautjwxvsMulticallable.huff b/src/utils/__TEMP__rrvaaiimcokotvnwlrlotlmzautjwxvsMulticallable.huff new file mode 100644 index 00000000..58569a85 --- /dev/null +++ b/src/utils/__TEMP__rrvaaiimcokotvnwlrlotlmzautjwxvsMulticallable.huff @@ -0,0 +1,233 @@ +#define function multicall(bytes[] calldata) payable returns (bytes[] memory) +#define function call1() view returns (uint256) +#define function call2() view returns (uint256) +#define function call3() view returns (uint256) +#define function returnsTuple(uint256, uint256) view returns (uint256, uint256) +#define function returnsStr(string) view returns (string) +#define function returnsSender() view returns (address) +#define function pay() payable returns (uint256) +#define function paid() view returns (uint256) +#define function revertsNoMsg() view returns () +#define function revertsMsg() view returns () + +#define constant PAID_SLOT = FREE_STORAGE_POINTER() + +#define macro CALL_1() = takes (0) returns (0) { + 0x11 0x00 mstore + 0x20 0x00 return +} + +#define macro CALL_2() = takes (0) returns (0) { + 0x22 0x00 mstore + 0x20 0x00 return +} + +#define macro CALL_3() = takes (0) returns (0) { + 0x33 0x00 mstore + 0x20 0x00 return +} + +#define macro RETURNS_TUPLE() = takes (0) returns (0) { + 0x04 calldataload // [x] + 0x00 mstore // [] + 0x24 calldataload // [y] + 0x20 mstore // [] + 0x40 0x00 return +} + +#define macro RETURNS_STR() = takes (0) returns (0) { + 0x24 calldataload // [str_len] + 0x40 add // [str_len + 0x40] + dup1 // [str_len + 0x40, str_len + 0x40] + 0x04 // [0x04, str_len + 0x40, str_len + 0x40] + 0x00 // [0x00, 0x04, str_len + 0x40, str_len + 0x40] + calldatacopy // [str_len + 0x40] + 0x00 return +} + +#define macro RETURNS_SENDER() = takes (0) returns (0) { + caller // [msg.sender] + 0x00 mstore // [] + 0x20 0x00 return +} + +#define macro PAY() = takes (0) returns (0) { + [PAID_SLOT] sload // [paid] + callvalue add // [paid + callvalue] + [PAID_SLOT] sstore // [] + 0x00 dup1 return +} + +#define macro PAID() = takes (0) returns (0) { + [PAID_SLOT] sload // [paid] + 0x00 mstore // [] + 0x20 0x00 return +} + +#define macro REVERTS_NO_MSG() = takes (0) returns (0) { + 0x00 dup1 revert +} + +#define macro REVERTS_MSG() = takes (0) returns (0) { + 0x5465737420526576657274000000000000000000000000000000000000000000 + 0x00 mstore + 0x0B 0x00 revert +} + +#define macro MAIN() = takes (0) returns (0) { + pc calldataload 0xE0 shr + dup1 __FUNC_SIG(multicall) eq multicall jumpi + dup1 __FUNC_SIG(call1) eq call_one jumpi + dup1 __FUNC_SIG(call2) eq call_two jumpi + dup1 __FUNC_SIG(call3) eq call_three jumpi + dup1 __FUNC_SIG(returnsTuple) eq returns_tuple jumpi + dup1 __FUNC_SIG(returnsStr) eq returns_str jumpi + dup1 __FUNC_SIG(returnsSender) eq returns_sender jumpi + dup1 __FUNC_SIG(pay) eq pay jumpi + dup1 __FUNC_SIG(paid) eq paid jumpi + dup1 __FUNC_SIG(revertsNoMsg) eq revert_no_msg jumpi + dup1 __FUNC_SIG(revertsMsg) eq revert_msg jumpi + + 0x00 dup1 revert + + multicall: + MULTICALL() + call_one: + CALL_1() + call_two: + CALL_2() + call_three: + CALL_3() + returns_tuple: + RETURNS_TUPLE() + returns_str: + RETURNS_STR() + returns_sender: + RETURNS_SENDER() + pay: + PAY() + paid: + PAID() + revert_no_msg: + REVERTS_NO_MSG() + revert_msg: + REVERTS_MSG() +} + +/// @title Multicallable +/// @notice SPDX-License-Identifier: MIT +/// @author clabby +/// @notice Enables a single call to call multiple methods within a contract. +/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/Multicallable.sol) +/// @author Adapted from Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/Multicallable.sol) + +// Calldata +#define constant DATA_LEN = 0x24 +#define constant DATA_OFFSET = 0x44 +// Memory +#define constant RES = 0x20 +#define constant RES_OFF = 0x40 + +/// @notice Multicall function entry point. +/// @dev This macro should be placed alone under a function selector's jump label. +/// +/// Expected calldata: `bytes[]` containing valid ABI-encoded function calls +/// as elements. +/// +/// Note: this macro only allows for multicalling functions that are within +/// the contract it is invoked in. +#define macro MULTICALL() = takes (0) returns (0) { + // Input stack: [] + + // Store pointer to array contents @ 0x00 + 0x20 0x00 mstore // [] + + [DATA_LEN] // [data_len_ptr] + calldataload // [data_len] + + // Only continue if data length is > 0 + dup1 continue jumpi + + // Return blank bytes array + 0x40 0x00 return + + continue: + + dup1 // [data_len, data_len] + [RES] // [res_ptr, data_len, data_len] + mstore // [data_len] + + [RES_OFF] // [results_offset, data_len] + + // Copy the offsets from calldata into memory. + swap1 // [data_len, results_offset] + 0x05 shl // [data_len * 0x20, results_offset] + dup1 // [data_len * 0x20, data_len * 0x20, results_offset] + [DATA_OFFSET] // [data_offset, data_len * 0x20, data_len * 0x20, results_offset] + dup4 // [results_offset, data_offset, data_len * 0x20, data_len * 0x20, results_offset] + calldatacopy // [data_len * 0x20, results_offset] + + dup2 add // [mem_ptr, results_offset] + dup1 // [data_end, mem_ptr, results_offset] + loop: + // The offset of the current bytes in the calldata. + dup3 // [results_offset, data_end, mem_ptr, results_offset] + mload // [result, data_end, mem_ptr, results_offset] + [DATA_OFFSET] // [0x44, result, data_end, mem_ptr, results_offset] + add // [o, data_end, mem_ptr, results_offset] + + // Copy the current bytes from calldata to the memory. + dup1 // [o, o, data_end, mem_ptr, results_offset] + calldataload // [cur_bytes_len, o, data_end, mem_ptr, results_offset] + dup2 0x20 add // [o + 0x20, cur_bytes_len, o, data_end, mem_ptr, results_offset] + dup5 // [mem_ptr, o + 0x20, cur_bytes_len, o, data_end, mem_ptr, results_offset] + calldatacopy // [o, data_end, mem_ptr, results_offset] + + calldataload // [cur_bytes_len, data_end, mem_ptr, results_offset] + 0x00 dup1 // [0x00, 0x00, cur_bytes_len, data_end, mem_ptr, results_offset] + swap2 // [cur_bytes_len, 0x00, 0x00, data_end, mem_ptr, results_offset] + dup5 // [mem_ptr, cur_bytes_len, 0x00, 0x00, data_end, mem_ptr, results_offset] + address // [self_addr, mem_ptr, cur_bytes_len, 0x00, 0x00, data_end, mem_ptr, results_offset] + gas // [gas, self_addr, mem_ptr, cur_bytes_len, 0x00, 0x00, data_end, mem_ptr, results_offset] + delegatecall // [call_result, data_end, mem_ptr, results_offset] + + // Bubble up the revert if the delegatecall reverts + iszero fail jumpi // [data_end, mem_ptr, results_offset] + + // Increment `results_offset` by 0x20 + 0x40 dup3 sub // [mem_ptr - 0x40, data_end, mem_ptr, results_offset] + dup4 mstore // [data_end, mem_ptr, results_offset] + dup3 0x20 add // [results_offset + 0x20, data_end, mem_ptr, results_offset] + swap3 pop // [data_end, mem_ptr, results_offset] + + // Append the `returndatasize()`, and the return data. + returndatasize // [ret_data_size, data_end, mem_ptr, results_offset] + dup3 // [mem_ptr, ret_data_size, data_end, mem_ptr, results_offset] + mstore // [data_end, mem_ptr, results_offset] + returndatasize // [ret_data_size, data_end, mem_ptr, results_offset] + 0x00 // [0x00, ret_data_size, data_end, mem_ptr, results_offset] + dup4 0x20 add // [mem_ptr + 0x20, 0x00, ret_data_size, data_end, mem_ptr, results_offset] + returndatacopy // [data_end, mem_ptr, results_offset] + + // Advance the `memPtr` by `returndatasize() + 0x20`, + // rounded up to the next multiple of 32. + 0xffffffffffffffe0 + 0x3f // [0x3f, 0xf..e0, data_end, mem_ptr, results_offset] + returndatasize // [ret_data_size, 0x3f, 0xf..e0, data_end, mem_ptr, results_offset] + dup5 add // [mem_ptr + ret_data_size, 0x3f, 0xf..e0, data_end, mem_ptr, results_offset] + add and // [(mem_ptr + ret_data_size + 0x3f) & 0xf..e0, data_end, mem_ptr, results_offset] + swap2 pop // [data_end, mem_ptr, results_offset] + + // Continue loop if results_offset < data_end + dup1 dup4 lt // [results_offset < data_end, data_end, mem_ptr, results_offset] + loop jumpi // [data_end, mem_ptr, results_offset] + + swap1 // [mem_ptr, data_end, results_offset] + 0x00 // [ret_mem_ptr, mem_ptr, data_end, results_offset] + return + fail: + returndatasize // [ret_data_size, data_end, mem_ptr, results_offset] + 0x00 dup1 // [0x00, 0x00, ret_data_size, data_end, mem_ptr, results_offset] + returndatacopy // [ret_data_size, data_end, mem_ptr, results_offset] + returndatasize 0x00 revert +} \ No newline at end of file diff --git a/src/utils/__TEMP__ryraejdcasobgumhdtbwarjszpnlvasmECDSA.huff b/src/utils/__TEMP__ryraejdcasobgumhdtbwarjszpnlvasmECDSA.huff new file mode 100644 index 00000000..be184d44 --- /dev/null +++ b/src/utils/__TEMP__ryraejdcasobgumhdtbwarjszpnlvasmECDSA.huff @@ -0,0 +1,305 @@ +#define function recoverCd(bytes32, bytes calldata) view returns (address) +#define function recoverShortSig(bytes32, bytes32, bytes32) view returns (address) +#define function recoverVRSSig(bytes32, bytes32, bytes32, bytes32) view returns (address) +#define function toEthSignedMessageHash(bytes32) view returns (bytes32) +#define function toEthSignedMessageHashDyn(bytes) view returns (bytes32) + +#define macro RECOVER_CD_WRAPPER() = { + RECOVER_CD_SIG(0x04, 0x64) // [result] + 0x00 mstore // [] + 0x20 0x00 return +} + +#define macro RECOVER_SHORT_SIG_WRAPPER() = { + 0x04 calldataload // [hash] + 0x24 calldataload // [r, hash] + 0x44 calldataload // [vs, r, hash] + RECOVER_SHORT_SIG() // [result] + 0x00 mstore // [] + 0x20 0x00 return +} + +#define macro RECOVER_VRS_SIG_WRAPPER() = { + 0x64 calldataload // [s] + 0x44 calldataload // [r, s] + 0x24 calldataload // [v, r, s] + 0x04 calldataload // [hash, v, r, s] + RECOVER_VRS_SIG() // [result] + 0x00 mstore // [] + 0x20 0x00 return +} + +#define macro TO_ETH_SIGNED_MSG_HASH_WRAPPER() = { + 0x04 calldataload // [hash] + TO_ETH_SIGNED_MSG_HASH() // [result] + 0x00 mstore // [] + 0x20 0x00 return +} + +#define macro TO_ETH_SIGNED_MSG_HASH_DYN_WRAPPER() = { + 0x24 calldataload // [len(s)] + 0x20 add // [len(s) + 0x20] + 0x24 0x60 calldatacopy // [] + TO_ETH_SIGNED_MSG_HASH_DYN(0x60) // [result] + 0x00 mstore // [] + 0x20 0x00 return +} + +#define macro MAIN() = { + pc calldataload 0xE0 shr + dup1 __FUNC_SIG(recoverCd) eq recover_cd jumpi + dup1 __FUNC_SIG(recoverShortSig) eq recover_short_sig jumpi + dup1 __FUNC_SIG(recoverVRSSig) eq recover_vrs_sig jumpi + dup1 __FUNC_SIG(toEthSignedMessageHash) eq to_eth_signed_msg_hash jumpi + dup1 __FUNC_SIG(toEthSignedMessageHashDyn) eq to_eth_signed_msg_hash_dyn jumpi + + // Revert if no function selectors match + 0x00 dup1 revert + + // Fn dispatch + recover_cd: + RECOVER_CD_WRAPPER() + recover_short_sig: + RECOVER_SHORT_SIG_WRAPPER() + recover_vrs_sig: + RECOVER_VRS_SIG_WRAPPER() + to_eth_signed_msg_hash: + TO_ETH_SIGNED_MSG_HASH_WRAPPER() + to_eth_signed_msg_hash_dyn: + TO_ETH_SIGNED_MSG_HASH_DYN_WRAPPER() +} + + +/// @title ECDSA +/// @notice Gas optimized ECDSA wrapper. +/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/ECDSA.sol) +/// @author Modified from Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/ECDSA.sol) +/// @author Modified from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/cryptography/ECDSA.sol) +/// @author clabby + +//////////////////////////////////////////////////////////////// +// CONSTANTS // +//////////////////////////////////////////////////////////////// + +/// @dev The number which `s` must not exceed in order for the signature to be non-malleable. +#define constant MALLEABILITY_THRESHOLD = 0x7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0 + +/// @dev Ethereum Signed Message header. Used in `TO_ETH_SIGNED_MSG_HASH` +#define constant SIG_HEADER = 0x0000000019457468657265756d205369676e6564204d6573736167653a0a3332 + +/// @dev Ethereum Signed Message header. Used in `TO_ETH_SIGNED_MSG_HASH_DYN` +#define constant SIG_HEADER_DYN = 0x00000000000019457468657265756d205369676e6564204d6573736167653a0a + +//////////////////////////////////////////////////////////////// +// RECOVERY OPERATIONS // +//////////////////////////////////////////////////////////////// + +/// @dev Recovers the signer's address from a message digest `hash`, +/// and the `signature`. +/// +/// This macro does NOT accept EIP-2098 short form signatures. +/// Use `recover(bytes32 hash, bytes32 r, bytes32 vs)` for EIP-2098 +/// short form signatures instead. +/// +/// WARNING! +/// The result will be the zero address upon recovery failure. +/// As such, it is extremely important to ensure that the address which +/// the result is compared against is never zero. +/// @notice The `sig_ptr` param must point to the *offset* of the signature data +/// in calldata. +#define macro RECOVER_CD_SIG(hash_ptr, sig_ptr) = returns (1) { + // Input stack: [] + + calldataload // [hash] + 0x20 sub // [sig_len_ptr, hash] + calldataload // [len(signature), hash] + + // If len(signature) != 65, jump to `zero`. + 0x41 eq iszero // [len(signature) != 0x41, hash] + zero jumpi // [hash] + + // Copy `r` and `s` from the calldata + 0x40 dup2 // [0x40, sig_ptr, 0x40, hash] + calldatacopy // [hash] + + // If `s` is not in lower half order, such that the signature is malleable, + // jump to `zero`. + [MALLEABILITY_THRESHOLD] // [malleability_threshold, hash] + 0x60 mload // [s, malleability_threshold, hash] + gt // [s > MALLEABILITY_THRESHOLD, hash] + zero jumpi // [hash] + + // Store `hash` in scratch space @ 0x00 + 0x00 mstore // [] + // Compute `v` and store it in scratch space @ 0x20 + 0x40 add // [0x40 + sig_ptr] + calldataload // [cd] + 0x00 byte // [v] + 0x20 mstore // [] + + 0x20 0x40 0x80 0x00 0x01 // [0x01, 0x00, 0x80, 0x40, 0x20] + gas staticcall pop // [] + + // Restore the zero slot + 0x00 0x60 mstore // [] + + // `returndatasize` will be `0x20` upon success, and `0x00` otherwise. + returndatasize 0x60 sub // [0x60 - returndatasize] + mload // [result] + end jump // [result] + + zero: + pop 0x00 // [0x00] + end: + + // Return stack: [result] +} + +/// @dev Recovers the signer's address from a message digest `hash`, +/// and the EIP-2098 short form signature defined by `r` and `vs`. +/// +/// This function only accepts EIP-2098 short form signatures. +/// See: https://eips.ethereum.org/EIPS/eip-2098 +/// +/// To be honest, I do not recommend using EIP-2098 signatures +/// for simplicity, performance, and security reasons. Most if not +/// all clients support traditional non EIP-2098 signatures by default. +/// As such, this method is intentionally not fully inlined. +/// It is merely included for completeness. - Vectorized +/// +/// WARNING! +/// The `result` will be the zero address upon recovery failure. +/// As such, it is extremely important to ensure that the address which +/// the `result` is compared against is never zero. +#define macro RECOVER_SHORT_SIG() = takes (3) returns (1) { + // Input stack: [vs, r, hash] + + dup1 0xFF shr 0x1B add // [v, vs, r, hash] + swap1 // [vs, v, r, hash] + 0x01 shl 0x01 shr // [s, v, r, hash] + swap3 // [hash, v, r, s] + RECOVER_VRS_SIG() // [result] + + // Return stack: [result] +} + +/// @dev Recovers the signer's address from a message digest `hash`, +/// and the signature defined by `v`, `r`, `s`. +/// +/// WARNING! +/// The `result` will be the zero address upon recovery failure. +/// As such, it is extremely important to ensure that the address which +/// the `result` is compared against is never zero. +#define macro RECOVER_VRS_SIG() = takes (4) returns (1) { + // Input stack: [hash, v, r, s] + + // If `s` is not in lower half order, such that the signature is malleable, + // jump to `zero`. + [MALLEABILITY_THRESHOLD] // [malleability_threshold, hash, v, r, s] + dup5 gt // [s > malleability_threshold, hash, v, r, s] + zero jumpi // [hash, v, r, s] + + 0x00 mstore // [v, r, s] + 0x20 mstore // [r, s] + 0x40 mstore // [s] + 0x60 mstore // [] + + 0x20 0x40 0x80 0x00 0x01 // [0x01, 0x00, 0x80, 0x40, 0x20] + gas staticcall pop // [] + + // Restore the zero slot + 0x00 0x60 mstore // [] + returndatasize 0x60 sub // [0x60 - returndatasize] + mload // [result] + end jump + + zero: + pop pop pop pop 0x00 // [0x00] + end: + + // Return stack: [result] +} + +/// @dev Returns an Ethereum Signed Message, created from a `hash`. +/// This produces a hash corresponding to the one signed with the +/// [`eth_sign`](https://eth.wiki/json-rpc/API#eth_sign) +/// JSON-RPC method as part of EIP-191. +#define macro TO_ETH_SIGNED_MSG_HASH() = takes (1) returns (1) { + // Input stack: [hash] + + // Store in scratch space for hashing. + 0x20 mstore // [] + [SIG_HEADER] 0x00 mstore // [] + + 0x3c 0x04 sha3 // [result] + + // Return stack: [result] +} +/// @dev Returns an Ethereum Signed Message, created from `s`. +/// This produces a hash corresponding to the one signed with the +/// [`eth_sign`](https://eth.wiki/json-rpc/API#eth_sign) +/// JSON-RPC method as part of EIP-191. +/// +/// @dev The msg *must* be stored at a memory offset >= 0x60. Otherwise, +/// the logic that restores the 128 bytes before the `msg_ptr` will +/// underflow, causing a revert due to excessive memory expansion. +#define macro TO_ETH_SIGNED_MSG_HASH_DYN(msg_ptr) = returns (1) { + // Input stack: [] + + // We need at most 128 bytes for Ethereum signed message header. + // The max length of the ASCII reprenstation of a uint256 is 78 bytes. + // The length of "\x19Ethereum Signed Message:\n" is 26 bytes (i.e. 0x1a). + // The next multiple of 32 above 78 + 26 is 128 (i.e. 0x80). + + // Instead of allocating, we temporarily copy the 128 bytes before the + // start of `msg` data to some variables. + // [msg_ptr] + 0x40 dup2 sub mload // [m2, msg_ptr] + 0x20 dup3 sub mload // [m1, m2, msg_ptr] + 0x60 dup4 sub mload // [m3, m1, m2, msg_ptr] + swap3 // [msg_ptr, m1, m2, m3] + dup1 mload // [len(msg), msg_ptr, m1, m2, m3] + + swap1 0x20 add // [ptr, len(msg), m1, m2, m3] + dup2 dup2 add // [end, ptr, len(msg), m1, m2, m3] + swap1 // [ptr, end, len(msg), m1, m2, m3] + dup3 swap1 // [ptr, temp, end, len(msg), m1, m2, m3] + + loop: + 0x01 swap1 sub // [ptr - 0x01, temp, end, len(msg), m1, m2, m3] + 0x0A dup3 mod // [temp % 0x0A, ptr, temp, end, len(msg), m1, m2, m3] + 0x30 add // [(temp % 0x0A) + 0x30, ptr, temp, end, len(msg), m1, m2, m3] + dup2 mstore8 // [ptr, temp, end, len(msg), m1, m2, m3] + 0x0A dup3 div // [temp / 0x0A, ptr, temp, end, len(msg), m1, m2, m3] + swap2 pop // [ptr, temp, end, len(msg), m1, m2, m3] + + // Continue loop if temp != 0 + dup2 loop jumpi // [ptr, temp, end, len(msg), m1, m2, m3] + + // Copy the header into memory. + [SIG_HEADER_DYN] // [sig_header, ptr, temp, end, len(msg), m1, m2, m3] + 0x20 dup3 sub // [ptr - 0x20, sig_header, ptr, temp, end, len(msg), m1, m2, m3] + mstore // [ptr, temp, end, len(msg), m1, m2, m3] + swap1 pop // [ptr, end, len(msg), m1, m2, m3] + + // Compute the keccak256 hash of the memory. + 0x1A swap1 sub // [ptr - 0x1A, end, len(msg), m1, m2, m3] + dup1 // [ptr - 0x1A, ptr - 0x1A, end, len(msg), m1, m2, m3] + swap2 sub // [end - (ptr - 0x1A), ptr - 0x1A, len(msg), m1, m2, m3] + swap1 // [ptr - 0x1A, end - (ptr - 0x1A), len(msg), m1, m2, m3] + sha3 // [result, len(msg), m1, m2, m3] + + // Restore the previous memory. + // TODO: Can keep msg_ptr on stack here and dup rather than pushing it + // 4 times. + swap4 // [m3, len(msg), m1, m2, result] + 0x60 sub // [sig_ptr - 0x60, m3, len(msg), m1, m2, result] + mstore // [len(msg), m1, m2, result] + mstore // [m1, m2, result] + 0x20 sub // [sig_ptr - 0x20, m1, m2, result] + mstore // [m2, result] + 0x40 sub // [sig_ptr - 0x40, m2, result] + mstore // [result] + + // Return stack: [result] +} diff --git a/src/utils/__TEMP__sjmfwvdxpickfrbtnbbaudfvqefkatoiRefunded.huff b/src/utils/__TEMP__sjmfwvdxpickfrbtnbbaudfvqefkatoiRefunded.huff new file mode 100644 index 00000000..6dde1042 --- /dev/null +++ b/src/utils/__TEMP__sjmfwvdxpickfrbtnbbaudfvqefkatoiRefunded.huff @@ -0,0 +1,97 @@ + +#define function refundedCall() payable returns () +#define function nonRefundedCall() payable returns () + +#define event NonRefundedCall(address) + +#define macro MAIN() = takes (0) returns (0) { + pc calldataload 0xe0 shr + + dup1 __FUNC_SIG(refundedCall) eq refunded_call jumpi + dup1 __FUNC_SIG(nonRefundedCall) eq non_refunded_call jumpi + + 0x00 dup1 revert + + refunded_logic: + caller __EVENT_HASH(NonRefundedCall) 0x00 0x00 log2 + __Refund_Return_Dest jump + + refunded_call: + REFUNDED(refunded_logic) + stop + non_refunded_call: + caller __EVENT_HASH(NonRefundedCall) 0x00 0x00 log2 + stop +} + +/// @title Refunded +/// @notice SPDX-License-Identifier: MIT +/// @author asnared +/// @notice Efficient gas refunds distributed through a modifier +/// @notice Adapted from Zolidity (https://github.com/z0r0z/zolidity/blob/main/src/utils/Refunded.sol) + +#include "./Errors.huff" +#include "./ReentrancyGuard.huff" + +/// @notice The base cost of refunding +#define constant BASE_COST = 0x6359 // 25433 + +/// @notice The maximum amount of gas that can be refunded +#define constant GAS_PRICE_MAX = 0x9502F9000 // 4e10 + +// Refunded custom errors +#define constant MAX_GAS_ERROR = 0x4d41585f47415300000000000000000000000000000000000000000000000000 +#define constant MAX_GAS_LENGTH = 0x07 + +/// @notice Refunds contract calls up to a maximum of 4e10 gas +/// @notice Modified functions over 21k gas benefit most from a refund +#define macro REFUNDED(dest) = takes (0) returns (0) { + // Get the starting amount of gas + gas // [gasLeft] + + // Prevent Reentrancy + LOCK() // [gasLeft] + + basefee [GAS_PRICE_MAX] add // [currMaxGas, gasLeft] + gasprice gt iszero // [!(gasPrice > currMaxGas), gasLeft] + __Safe_Gas_Refund__j jumpi // [gasLeft] + MAX_GAS(0x00) + + __Safe_Gas_Refund__j: + + // The below attempts to mimic `_;` using a jump + // NOTE: This must jump back to `__Refund_Return_Dest` to complete the refund + jump + __Refund_Return_Dest: + + // Calculate refund amount + gas swap1 sub // [gasUsed] + [BASE_COST] add // [gasUsed + BASE_COST] + gasprice mul // [(gasUsed + BASE_COST) * gasPrice] + + // Refund the gas to origin + 0x00 // [retOffset, value] + 0x00 // [argSize, retOffset, value] + 0x00 // [argOffset, argSize, retOffset, value] + 0x00 // [retSize, argOffset, argSize, retOffset, value] + swap4 // [value, argOffset, argSize, retOffset, retSize] + origin // [to, value, argOffset, argSize, retOffset, retSize] + gas // [gas, to, value, argOffset, argSize, retOffset, retSize] + call + iszero iszero __Refund_Successful__j jumpi + 0x00 dup1 revert + + // The refund was successful! + __Refund_Successful__j: + + // Finally, unlock the guard + UNLOCK() +} + +/// @notice Reverts with an "MAX_GAS" message if the condition is false +#define macro MAX_GAS(condition) = takes (0) returns (0) { + [MAX_GAS_ERROR] // ["MAX_GAS"] + [MAX_GAS_LENGTH] // [7 (length), "MAX_GAS"] + // [condition, 7 (length), "MAX_GAS"] + REQUIRE() // [] +} \ No newline at end of file diff --git a/src/utils/__TEMP__sqowhqjsqxheosskvfeygpuobkhcslnvMerkleDistributor.huff b/src/utils/__TEMP__sqowhqjsqxheosskvfeygpuobkhcslnvMerkleDistributor.huff new file mode 100644 index 00000000..867e8160 --- /dev/null +++ b/src/utils/__TEMP__sqowhqjsqxheosskvfeygpuobkhcslnvMerkleDistributor.huff @@ -0,0 +1,247 @@ + +#define macro CONSTRUCTOR() = takes (0) returns (0) { + MERKLE_DISTRIBUTOR_CONSTRUCTOR() +} + +#define macro MAIN() = takes (0) returns (0) { + pc calldataload 0xE0 shr + MERKLE_DISTRIBUTOR_MAIN() + 0x00 dup1 revert +} + + +/// @title Merkle Distributor +/// @notice SPDX-License-Identifier: MIT +/// @author Ben Leimberger +/// @author Magna +/// @author asnared +/// @notice Minimal, gas efficient Merkle Distributor implementation + + +// Imports +#include "./CommonErrors.huff" +#include "./MerkleProofLib.huff" +#include "./Address.huff" +#include "./ERC20Transfer.huff" + +// Interface +#define function claim(uint256,address,uint256,bytes32[]) nonpayable returns () + +#define function getMerkleRoot() view returns (bytes32) +#define function getTokenAddress() view returns (address) +#define function isClaimed(uint256) view returns (bool) + +// Storage Slots +#define constant CLAIMED_BIT_MAP_SLOT = FREE_STORAGE_POINTER() // 0x00 +#define constant TOKEN_ADDR_SLOT = FREE_STORAGE_POINTER() // 0x01 +#define constant MERKLE_ROOT_SLOT = FREE_STORAGE_POINTER() // 0x02 + +// Errors +#define error TransferError(string) +#define error ClaimedError(string) +#define error ProofError(string) + + +/// @notice Get Merkle Root +/// @notice Entry point for: getMerkleRoot() +/// @dev Fetches merkle root from storage slot +/// @param {calldata} [] +/// @return {return} [bytes32 root] +#define macro GET_MERKLE_ROOT() = takes (0) returns (0) { + // Load value from storage + [MERKLE_ROOT_SLOT] sload // [merkle_root] + + // Store value in memory + 0x00 mstore // [] + + // Return value + 0x20 0x00 return // [] +} + +/// @notice Get Token Address +#define macro GET_TOKEN_ADDR() = takes (0) returns (0) { + // Load value from storage + [TOKEN_ADDR_SLOT] sload // [token_addr] + + // Store value in memory + 0x00 mstore // [] + + // Return value + 0x20 0x00 return // [] +} + + +/// Is Claimed +/// @notice Entry point for: isClaimed(uint256) +/// @dev Check if index is claimed +/// @param {calldata} [uint256 index] +/// @return {return} [bytes32 root] +#define macro IS_CLAIMED() = takes (0) returns (0) { + // Load first argument from calldata + 0x04 calldataload // [index] + + // Utility macro + __UTIL_IS_CLAIMED() // [isEqual] + + // store result in memory + 0x00 mstore // [] + 0x20 0x00 return +} + +/// @dev stores result in 0x00 to 0x20 memory slot +#define macro __UTIL_IS_CLAIMED() = takes (1) returns (1) { + // Stack input: // [arg0] + // Stack output: // [isEqual] + // index / 256 + 0x100 dup2 div // [index] + + __UTIL_GENERATE_MAPPING_KEY() // [key(claimed[index]), arg0] + + // Load mapping key + sload // [claimed[index], arg0] + + // index % 256 [claimed[index], arg0] + 0x1 0x100 dup4 mod shl // [mask, claimed[index], arg0] + dup1 swap2 dup2 and // [masked, mask, claimed[index], arg0] + eq // [isEqual, claimed[index], arg0] + swap2 pop pop // [isEqual] +} + + +/// @notice Set as claimed +#define macro __UTIL_SET_CLAIMED() = takes (1) returns (0) { + // Stack input: // [arg0] + + // index / 256 + 0x100 dup2 div // [index, arg0] + + __UTIL_GENERATE_MAPPING_KEY() // [key(claimed[index]), arg0] + + // Load mapping key + dup1 sload // [claimed[index], key(claimed[index]), arg0] + + // index % 256 [claimed[index], key(claimed[index]), arg0] + 0x1 0x100 dup5 mod shl // [mask, claimed[index], key(claimed[index]), arg0] + or // [masked, key(claimed[to]), arg0] + + // Update + swap1 sstore pop // [] +} + +/// @notice Creates a mapping key from an index +#define macro __UTIL_GENERATE_MAPPING_KEY() = takes (1) returns (1) { + // Stack input: [index] + // Stack output: [key(claimed[index])] + 0x00 mstore // [] + [CLAIMED_BIT_MAP_SLOT] 0x20 mstore // [] + + // key(claimed[index]) = keccak256(index . claimedBitMapSlot) + 0x40 0x00 sha3 // [key(claimed[index])] +} + +/// @notice Claim +/// @notice Entry point for: claim(uint256,address,uint256,bytes[]) +/// @dev Claim distribution with proof +/// @param {calldata} [uint256 index, address account, uint256 amount, bytes[] proof] +/// @return {return} [] +#define macro CLAIM() = takes (0) returns (0) { + // Preload merkle root + [MERKLE_ROOT_SLOT] sload // [root] + + // Load arguments from calldata + 0x44 calldataload // [amount, root] + 0x24 calldataload MASK_ADDRESS() // [account, amount, root] + 0x04 calldataload // [index, account, amount, root] + + // Check if an index is claimed + dup1 __UTIL_IS_CLAIMED() // [isClaimed, index, account, amount, root] + iszero cont jumpi // [index, account, amount, root] + ALREADY_CLAIMED(0x00) + cont: + + // EncodePacked + // [ 32 bytes | 20 bytes | 32 bytes ] = 84 bytes + 0x00 mstore // [account, amount, root] + 0x60 shl // [account << 12, amount, root] + 0x20 mstore // [amount, root] + 0x34 mstore // [root] + 0x54 0x00 sha3 // [leaf, root] + + // Verify merkle proof + 0x64 calldataload 0x4 add // [&proof_length, leaf, root] + + // Required() + VERIFY_PROOF() // [isProven] + verified jumpi // [] + INVALID_PROOF(0x00) + verified: + + // Mark it claimed + 0x04 calldataload // [arg0] + __UTIL_SET_CLAIMED() // [] + + // Load other calldata arguments + [TOKEN_ADDR_SLOT] sload // [getter_addr] + 0x44 calldataload // [amount, getter_addr] + 0x24 calldataload // [address_raw, amount, getter_addr] + MASK_ADDRESS() // [address, amount, getter_addr] + + // Send the token + ERC20_TRANSFER() + + // Finish Execution + stop +} + +/// @notice Constructor +/// @param address The address of the token to distribute +/// @param merkleRoot The merkle root of the merkle tree +#define macro MERKLE_DISTRIBUTOR_CONSTRUCTOR() = takes (0) returns (0) { + // Copy the first argument into memory + 0x20 // [size] - byte size to copy + 0x40 codesize sub // [offset, size] - offset in the code to copy from + 0x00 // [mem, offset, size] - offset in memory to copy to + codecopy // [] + + // Store the first argument in storage + 0x00 mload // [arg1] + [TOKEN_ADDR_SLOT] // [TOKEN_ADDR, arg1] + sstore // [] + + // Copy the second argument into memory + 0x20 // [size] - byte size to copy + 0x20 codesize sub // [offset, size] - offset in the code to copy from + 0x00 // [mem, offset, size] - offset in memory to copy to + codecopy // [] + + // Store the second argument in storage + 0x00 mload // [arg2] + [MERKLE_ROOT_SLOT] // [CONSTRUCTOR_ARG_TWO, arg2] + sstore // [] +} + +/// @notice Function Dispatch +/// @notice Takes the first 4 bytes of calldata (aka the function selector) and dispatches to the appropriate function +/// @notice If non match, execution proceeds as the code is inlined +#define macro MERKLE_DISTRIBUTOR_MAIN() = takes (1) returns (1) { + // Input Stack: [function_selector] + + dup1 __FUNC_SIG(getTokenAddress) eq getTokenAddress jumpi + dup1 __FUNC_SIG(getMerkleRoot) eq getMerkleRoot jumpi + dup1 __FUNC_SIG(isClaimed) eq isClaimed jumpi + dup1 __FUNC_SIG(claim) eq claim jumpi + + // Jump to the end if non match + no_match jump + + getMerkleRoot: + GET_MERKLE_ROOT() + getTokenAddress: + GET_TOKEN_ADDR() + isClaimed: + IS_CLAIMED() + claim: + CLAIM() + + no_match: +} \ No newline at end of file diff --git a/src/utils/__TEMP__syuldunwuhcelrjhrahufjtvdthjstmmMulticallable.huff b/src/utils/__TEMP__syuldunwuhcelrjhrahufjtvdthjstmmMulticallable.huff new file mode 100644 index 00000000..58569a85 --- /dev/null +++ b/src/utils/__TEMP__syuldunwuhcelrjhrahufjtvdthjstmmMulticallable.huff @@ -0,0 +1,233 @@ +#define function multicall(bytes[] calldata) payable returns (bytes[] memory) +#define function call1() view returns (uint256) +#define function call2() view returns (uint256) +#define function call3() view returns (uint256) +#define function returnsTuple(uint256, uint256) view returns (uint256, uint256) +#define function returnsStr(string) view returns (string) +#define function returnsSender() view returns (address) +#define function pay() payable returns (uint256) +#define function paid() view returns (uint256) +#define function revertsNoMsg() view returns () +#define function revertsMsg() view returns () + +#define constant PAID_SLOT = FREE_STORAGE_POINTER() + +#define macro CALL_1() = takes (0) returns (0) { + 0x11 0x00 mstore + 0x20 0x00 return +} + +#define macro CALL_2() = takes (0) returns (0) { + 0x22 0x00 mstore + 0x20 0x00 return +} + +#define macro CALL_3() = takes (0) returns (0) { + 0x33 0x00 mstore + 0x20 0x00 return +} + +#define macro RETURNS_TUPLE() = takes (0) returns (0) { + 0x04 calldataload // [x] + 0x00 mstore // [] + 0x24 calldataload // [y] + 0x20 mstore // [] + 0x40 0x00 return +} + +#define macro RETURNS_STR() = takes (0) returns (0) { + 0x24 calldataload // [str_len] + 0x40 add // [str_len + 0x40] + dup1 // [str_len + 0x40, str_len + 0x40] + 0x04 // [0x04, str_len + 0x40, str_len + 0x40] + 0x00 // [0x00, 0x04, str_len + 0x40, str_len + 0x40] + calldatacopy // [str_len + 0x40] + 0x00 return +} + +#define macro RETURNS_SENDER() = takes (0) returns (0) { + caller // [msg.sender] + 0x00 mstore // [] + 0x20 0x00 return +} + +#define macro PAY() = takes (0) returns (0) { + [PAID_SLOT] sload // [paid] + callvalue add // [paid + callvalue] + [PAID_SLOT] sstore // [] + 0x00 dup1 return +} + +#define macro PAID() = takes (0) returns (0) { + [PAID_SLOT] sload // [paid] + 0x00 mstore // [] + 0x20 0x00 return +} + +#define macro REVERTS_NO_MSG() = takes (0) returns (0) { + 0x00 dup1 revert +} + +#define macro REVERTS_MSG() = takes (0) returns (0) { + 0x5465737420526576657274000000000000000000000000000000000000000000 + 0x00 mstore + 0x0B 0x00 revert +} + +#define macro MAIN() = takes (0) returns (0) { + pc calldataload 0xE0 shr + dup1 __FUNC_SIG(multicall) eq multicall jumpi + dup1 __FUNC_SIG(call1) eq call_one jumpi + dup1 __FUNC_SIG(call2) eq call_two jumpi + dup1 __FUNC_SIG(call3) eq call_three jumpi + dup1 __FUNC_SIG(returnsTuple) eq returns_tuple jumpi + dup1 __FUNC_SIG(returnsStr) eq returns_str jumpi + dup1 __FUNC_SIG(returnsSender) eq returns_sender jumpi + dup1 __FUNC_SIG(pay) eq pay jumpi + dup1 __FUNC_SIG(paid) eq paid jumpi + dup1 __FUNC_SIG(revertsNoMsg) eq revert_no_msg jumpi + dup1 __FUNC_SIG(revertsMsg) eq revert_msg jumpi + + 0x00 dup1 revert + + multicall: + MULTICALL() + call_one: + CALL_1() + call_two: + CALL_2() + call_three: + CALL_3() + returns_tuple: + RETURNS_TUPLE() + returns_str: + RETURNS_STR() + returns_sender: + RETURNS_SENDER() + pay: + PAY() + paid: + PAID() + revert_no_msg: + REVERTS_NO_MSG() + revert_msg: + REVERTS_MSG() +} + +/// @title Multicallable +/// @notice SPDX-License-Identifier: MIT +/// @author clabby +/// @notice Enables a single call to call multiple methods within a contract. +/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/Multicallable.sol) +/// @author Adapted from Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/Multicallable.sol) + +// Calldata +#define constant DATA_LEN = 0x24 +#define constant DATA_OFFSET = 0x44 +// Memory +#define constant RES = 0x20 +#define constant RES_OFF = 0x40 + +/// @notice Multicall function entry point. +/// @dev This macro should be placed alone under a function selector's jump label. +/// +/// Expected calldata: `bytes[]` containing valid ABI-encoded function calls +/// as elements. +/// +/// Note: this macro only allows for multicalling functions that are within +/// the contract it is invoked in. +#define macro MULTICALL() = takes (0) returns (0) { + // Input stack: [] + + // Store pointer to array contents @ 0x00 + 0x20 0x00 mstore // [] + + [DATA_LEN] // [data_len_ptr] + calldataload // [data_len] + + // Only continue if data length is > 0 + dup1 continue jumpi + + // Return blank bytes array + 0x40 0x00 return + + continue: + + dup1 // [data_len, data_len] + [RES] // [res_ptr, data_len, data_len] + mstore // [data_len] + + [RES_OFF] // [results_offset, data_len] + + // Copy the offsets from calldata into memory. + swap1 // [data_len, results_offset] + 0x05 shl // [data_len * 0x20, results_offset] + dup1 // [data_len * 0x20, data_len * 0x20, results_offset] + [DATA_OFFSET] // [data_offset, data_len * 0x20, data_len * 0x20, results_offset] + dup4 // [results_offset, data_offset, data_len * 0x20, data_len * 0x20, results_offset] + calldatacopy // [data_len * 0x20, results_offset] + + dup2 add // [mem_ptr, results_offset] + dup1 // [data_end, mem_ptr, results_offset] + loop: + // The offset of the current bytes in the calldata. + dup3 // [results_offset, data_end, mem_ptr, results_offset] + mload // [result, data_end, mem_ptr, results_offset] + [DATA_OFFSET] // [0x44, result, data_end, mem_ptr, results_offset] + add // [o, data_end, mem_ptr, results_offset] + + // Copy the current bytes from calldata to the memory. + dup1 // [o, o, data_end, mem_ptr, results_offset] + calldataload // [cur_bytes_len, o, data_end, mem_ptr, results_offset] + dup2 0x20 add // [o + 0x20, cur_bytes_len, o, data_end, mem_ptr, results_offset] + dup5 // [mem_ptr, o + 0x20, cur_bytes_len, o, data_end, mem_ptr, results_offset] + calldatacopy // [o, data_end, mem_ptr, results_offset] + + calldataload // [cur_bytes_len, data_end, mem_ptr, results_offset] + 0x00 dup1 // [0x00, 0x00, cur_bytes_len, data_end, mem_ptr, results_offset] + swap2 // [cur_bytes_len, 0x00, 0x00, data_end, mem_ptr, results_offset] + dup5 // [mem_ptr, cur_bytes_len, 0x00, 0x00, data_end, mem_ptr, results_offset] + address // [self_addr, mem_ptr, cur_bytes_len, 0x00, 0x00, data_end, mem_ptr, results_offset] + gas // [gas, self_addr, mem_ptr, cur_bytes_len, 0x00, 0x00, data_end, mem_ptr, results_offset] + delegatecall // [call_result, data_end, mem_ptr, results_offset] + + // Bubble up the revert if the delegatecall reverts + iszero fail jumpi // [data_end, mem_ptr, results_offset] + + // Increment `results_offset` by 0x20 + 0x40 dup3 sub // [mem_ptr - 0x40, data_end, mem_ptr, results_offset] + dup4 mstore // [data_end, mem_ptr, results_offset] + dup3 0x20 add // [results_offset + 0x20, data_end, mem_ptr, results_offset] + swap3 pop // [data_end, mem_ptr, results_offset] + + // Append the `returndatasize()`, and the return data. + returndatasize // [ret_data_size, data_end, mem_ptr, results_offset] + dup3 // [mem_ptr, ret_data_size, data_end, mem_ptr, results_offset] + mstore // [data_end, mem_ptr, results_offset] + returndatasize // [ret_data_size, data_end, mem_ptr, results_offset] + 0x00 // [0x00, ret_data_size, data_end, mem_ptr, results_offset] + dup4 0x20 add // [mem_ptr + 0x20, 0x00, ret_data_size, data_end, mem_ptr, results_offset] + returndatacopy // [data_end, mem_ptr, results_offset] + + // Advance the `memPtr` by `returndatasize() + 0x20`, + // rounded up to the next multiple of 32. + 0xffffffffffffffe0 + 0x3f // [0x3f, 0xf..e0, data_end, mem_ptr, results_offset] + returndatasize // [ret_data_size, 0x3f, 0xf..e0, data_end, mem_ptr, results_offset] + dup5 add // [mem_ptr + ret_data_size, 0x3f, 0xf..e0, data_end, mem_ptr, results_offset] + add and // [(mem_ptr + ret_data_size + 0x3f) & 0xf..e0, data_end, mem_ptr, results_offset] + swap2 pop // [data_end, mem_ptr, results_offset] + + // Continue loop if results_offset < data_end + dup1 dup4 lt // [results_offset < data_end, data_end, mem_ptr, results_offset] + loop jumpi // [data_end, mem_ptr, results_offset] + + swap1 // [mem_ptr, data_end, results_offset] + 0x00 // [ret_mem_ptr, mem_ptr, data_end, results_offset] + return + fail: + returndatasize // [ret_data_size, data_end, mem_ptr, results_offset] + 0x00 dup1 // [0x00, 0x00, ret_data_size, data_end, mem_ptr, results_offset] + returndatacopy // [ret_data_size, data_end, mem_ptr, results_offset] + returndatasize 0x00 revert +} \ No newline at end of file diff --git a/src/utils/__TEMP__tvibuicjahwdnvquznelrjppmvqtmvduSafeTransferLib.huff b/src/utils/__TEMP__tvibuicjahwdnvquznelrjppmvqtmvduSafeTransferLib.huff new file mode 100644 index 00000000..e62c27e4 --- /dev/null +++ b/src/utils/__TEMP__tvibuicjahwdnvquznelrjppmvqtmvduSafeTransferLib.huff @@ -0,0 +1,202 @@ +#define function safeTransferETH(address, uint256) payable returns () +#define function safeTransferFrom(address, address, address, uint256) nonpayable returns () +#define function safeTransfer(address, address, uint256) nonpayable returns () +#define function safeApprove(address, address, uint256) nonpayable returns () + +#define macro SAFE_TRANSFER_ETH_WRAPPER() = { + 0x24 calldataload // [amount] + 0x04 calldataload // [to, amount] + + SAFE_TRANSFER_ETH() + stop +} + +#define macro SAFE_TRANSFER_FROM_WRAPPER() = { + 0x04 calldataload // [token] + 0x64 calldataload // [amount, token] + 0x44 calldataload // [to, amount, token] + 0x24 calldataload // [from, to, amount, token] + + SAFE_TRANSFER_FROM(0x00) + stop +} + +#define macro SAFE_TRANSFER_WRAPPER() = { + 0x04 calldataload // [token] + 0x44 calldataload // [amount, token] + 0x24 calldataload // [to, amount, token] + + SAFE_TRANSFER(0x00) + stop +} + +#define macro SAFE_APPROVE_WRAPPER() = { + 0x04 calldataload // [token] + 0x44 calldataload // [amount, token] + 0x24 calldataload // [to, amount, token] + + SAFE_APPROVE(0x00) + stop +} + +#define macro MAIN() = { + pc calldataload 0xE0 shr + dup1 __FUNC_SIG(safeTransferETH) eq steth jumpi + dup1 __FUNC_SIG(safeTransferFrom) eq stf jumpi + dup1 __FUNC_SIG(safeTransfer) eq st jumpi + dup1 __FUNC_SIG(safeApprove) eq sa jumpi + + 0x00 dup1 revert + + steth: + SAFE_TRANSFER_ETH_WRAPPER() + stf: + SAFE_TRANSFER_FROM_WRAPPER() + st: + SAFE_TRANSFER_WRAPPER() + sa: + SAFE_APPROVE_WRAPPER() +} + + +/// @title SafeTransferLib +/// @notice SPDX-License-Identifier: MIT +/// @notice Safe ETH and ERC20 transfer library that gracefully handles missing return values. +/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/SafeTransferLib.sol) +/// @author Modified from Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/SafeTransferLib.sol) +/// @author clabby +/// @dev Caution! This library won't check that a token has code, responsibility is delegated to the caller. + +/// CONSIDERATION: +/// We could designate byte scratch space for memory +/// which would spare us runtime operations shifting the dynamic memory pointer +/// +/// Designations: +/// - 128 bytes for SAFE_TRANSFER_FROM +/// - 96 bytes for SAFE_TRANSFER +/// - 96 bytes for SAFE_APPROVE + + +/// @notice Safely transfers an `amount` of eth to the address `to` +#define macro SAFE_TRANSFER_ETH() = takes (2) { + // Input stack: [to, amount] + // Output stack: [] + + 0x00 dup1 dup1 dup1 // [0x00, 0x00, 0x00, 0x00, to, amount] + swap5 swap1 swap4 // [to, amount, 0x00, 0x00, 0x00, 0x00] + gas call // [call_success] + success jumpi // [] + + // `ETHTransferFailed()` error + 0xb12d13eb 0x00 mstore + 0x04 0x1c revert + + success: +} + +/// @notice Safely transfers an `amount` of `token` from an address `from` to the address `to` +#define macro SAFE_TRANSFER_FROM(mem_ptr) = takes (4) { + // Input stack: [from, to, value, token] + // Output stack: [] + + __RIGHTPAD(0x23b872dd) // [transferFrom_selector, from, to, amount, token] + // [mem_ptr, transferFrom_selector, from, to, amount, token] + mstore // [from, to, amount, token] + + 0x04 add // [mem_ptr + 0x04, from, to, amount, token] + mstore // [to, amount, token] + 0x24 add // [mem_ptr + 0x24, to, amount, token] + mstore // [amount, token] + 0x44 add // [mem_ptr + 0x44, amount, token] + mstore // [token] + + 0x64 // [0x64, mem_ptr, token] + dup2 0x00 // [0x00, mem_ptr, 0x64, mem_ptr, token] + 0x20 swap5 // [token, 0x00, mem_ptr, 0x64, mem_ptr, 0x20] + gas call // [success] + + returndatasize // [returndatasize, success] + iszero // [returndatasize == 0, success] + // [offset, returndatasize == 0, success] + mload // [data, returndatasize == 0, success] + 0x01 eq // [data == 0x01, returndatasize == 0, success] + or // [data == 0x01 | returndatasize == 0, success] + + and // [success & (data == 0x01 | returndatasize == 0)] + success jumpi // [] + + 0x7939f424 0x00 mstore + 0x04 0x1c revert + + success: +} + +/// @notice Safely transfers an `amount` to an address `to` for the provided `token` +#define macro SAFE_TRANSFER(mem_ptr) = takes (3) { + // Input stack: [to, amount, token] + // Output stack: [] + + __RIGHTPAD(0xa9059cbb) // [transfer_selector, to, amount, token] + // [mem_ptr, transfer_selector, to, amount, token] + mstore // [to, amount, token] + + 0x04 add // [mem_ptr + 0x04, to, amount, token] + mstore // [amount, token] + 0x24 add // [mem_ptr + 0x24, amount, token] + mstore + + 0x44 // [0x44, mem_ptr, token] + dup2 0x00 // [0x00, mem_ptr, 0x44, mem_ptr, token] + 0x20 swap5 // [token, 0x00, mem_ptr, 0x44, mem_ptr, 0x20] + gas call // [success] + + returndatasize // [returndatasize, success] + iszero // [returndatasize == 0, success] + // [offset, returndatasize == 0, success] + mload // [data, returndatasize == 0, success] + 0x01 eq // [data == 0x01, returndatasize == 0, success] + or // [data == 0x01 | returndatasize == 0, success] + + and // [success & (data == 0x01 | returndatasize == 0)] + success jumpi // [] + + 0x90b8ec18 0x00 mstore + 0x04 0x1c revert + + success: +} + +/// @notice Safely approves an `amount` for an address `to` for the provided `token` +#define macro SAFE_APPROVE(mem_ptr) = takes (3) { + // Input stack: [spender, value, token] + // Output stack: [] + + __RIGHTPAD(0x095ea7b3) // [approve_selector, to, amount, token] + // [mem_ptr, approve_selector, to, amount, token] + mstore // [to, amount, token] + + 0x04 add // [mem_ptr + 0x04, to, amount, token] + mstore // [amount, token] + 0x24 add // [mem_ptr + 0x24, amount, token] + mstore + + 0x44 // [0x44, mem_ptr, token] + dup2 0x00 // [0x00, mem_ptr, 0x44, mem_ptr, token] + 0x20 swap5 // [token, 0x00, mem_ptr, 0x44, mem_ptr, 0x20] + gas call // [success] + + returndatasize // [returndatasize, success] + iszero // [returndatasize == 0, success] + // [offset, returndatasize == 0, success] + mload // [data, returndatasize == 0, success] + 0x01 eq // [data == 0x01, returndatasize == 0, success] + or // [data == 0x01 | returndatasize == 0, success] + + and // [success & (data == 0x01 | returndatasize == 0)] + success jumpi // [] + + 0x3e3f8f73 0x00 mstore + 0x04 0x1c revert + + success: +} diff --git a/src/utils/__TEMP__ubhvkcstcqznkwuhmkwwvrdjviacaricEthers.huff b/src/utils/__TEMP__ubhvkcstcqznkwuhmkwwvrdjviacaricEthers.huff new file mode 100644 index 00000000..12fda5c0 --- /dev/null +++ b/src/utils/__TEMP__ubhvkcstcqznkwuhmkwwvrdjviacaricEthers.huff @@ -0,0 +1,47 @@ + +// Receives ether +#define function isPayable() payable returns (uint256) +#define function nonPayable() nonpayable returns (uint256) + +// Match the function selector +#define macro MAIN() = takes (0) returns (0) { + pc calldataload 0xe0 shr + + dup1 __FUNC_SIG(isPayable) eq payable_jump jumpi + dup1 __FUNC_SIG(nonPayable) eq non_payable_jump jumpi + + // Revert if no function selectors match + reverts: + 0x00 dup1 revert + + non_payable_jump: + callvalue iszero iszero reverts jumpi + payable_jump: + balance 0x00 mstore + 0x20 0x00 return +} + +/// @title Ethers +/// @notice SPDX-License-Identifier: MIT +/// @author asnared +/// @notice Utilities for working with ether at a low level + +/// @notice Sends an amount of ether to the specified [amount, address] +#define macro SEND_ETH() = takes (2) returns (1) { + // Input Stack: [amount, address] + + // Send the ether + 0x00 // [0, amount, address] + dup1 // [0, 0, amount, address] + dup1 // [0, 0, 0, amount, address] + dup1 // [0, 0, 0, 0, amount, address] + dup5 // [amount, 0, 0, 0, 0, amount, address] + dup7 // [address, amount, 0, 0, 0, 0, amount] + gas // [gas, address, amount, 0, 0, 0, 0, amount, address] + call // [success, amount, address] + + // Clean the stack + swap2 // [address, amount, success] + pop // [success, address] + pop // [success] +} \ No newline at end of file diff --git a/src/utils/__TEMP__vamkrwmxfmambbznmfrsntcscmmocveeDateTimeLib.huff b/src/utils/__TEMP__vamkrwmxfmambbznmfrsntcscmmocveeDateTimeLib.huff new file mode 100644 index 00000000..04bae5ed --- /dev/null +++ b/src/utils/__TEMP__vamkrwmxfmambbznmfrsntcscmmocveeDateTimeLib.huff @@ -0,0 +1,517 @@ +/* Functions */ +#define function weekday(uint256) nonpayable returns (uint256) +#define function isLeapYear(uint256) nonpayable returns (bool) +#define function daysInMonth(uint256,uint256) nonpayable returns (uint256) +#define function dateToEpochDay(uint256,uint256,uint256) nonpayable returns (uint256) +#define function dateToTimestamp(uint256,uint256,uint256) nonpayable returns (uint256) +#define function dateTimeToTimestamp(uint256,uint256,uint256,uint256,uint256,uint256) nonpayable returns (uint256) +#define function nthWeekdayInMonthOfYearTimestamp(uint256, uint256,uint256,uint256) nonpayable returns (uint256) +#define function epochDayToDate(uint256) nonpayable returns (uint256,uint256,uint256) +#define function timestampToDate(uint256) nonpayable returns (uint256,uint256,uint256) + +/* Wrapper Macros */ +#define macro WEEKDAY_WRAPPER() = takes (0) returns (0) { + 0x04 calldataload // [timestamp] + WEEKDAY() // [result] + 0x00 mstore // [] + 0x20 0x00 return // [] + } + +#define macro IS_LEAP_YEAR_WRAPPER() = takes (0) returns (0) { + 0x04 calldataload // [timestamp] + IS_LEAP_YEAR() // [result] + 0x00 mstore // [] + 0x20 0x00 return // [] + } + +#define macro DAYS_IN_MONTH_WRAPPER() = takes (0) returns (0) { + 0x04 calldataload // [year] + 0x24 calldataload // [month, year] + DAYS_IN_MONTH() // [result] + 0x00 mstore // [] + 0x20 0x00 return // [] + } + +#define macro DATE_TO_EPOCH_DAY_WRAPPER() = takes (0) returns (0) { + 0x04 calldataload // [year] + 0x24 calldataload // [month, year] + 0x44 calldataload // [day, month, year] + DATE_TO_EPOCH_DAY() // [result] + 0x00 mstore // [] + 0x20 0x00 return // [] + } + + #define macro DATE_TO_TIMESTAMP_WRAPPER() = takes (0) returns (0) { + 0x04 calldataload // [year] + 0x24 calldataload // [month, year] + 0x44 calldataload // [day, month, year] + DATE_TO_TIMESTAMP() // [result] + 0x00 mstore // [] + 0x20 0x00 return // [] + } + + #define macro DATE_TIME_TO_TIMESTAMP_WRAPPER() = takes (0) returns (0) { + 0x04 calldataload // [year] + 0x24 calldataload // [month, year] + 0x44 calldataload // [day, month, year] + 0x64 calldataload // [seconds, day, month, year] + 0x84 calldataload // [minutes, seconds, day, month, year] + 0xa4 calldataload // [hours, minutes, seconds, day, month, year] + DATE_TIME_TO_TIMESTAMP() // [result] + 0x00 mstore // [] + 0x20 0x00 return // [] + } + + #define macro EPOCH_DAY_TO_DATE_WRAPPER() = takes (0) returns (0) { + 0x04 calldataload // [epochDay] + EPOCH_DAY_TO_DATE() // [year, month, day] + 0x00 mstore // [month, day] + 0x20 mstore // [day] + 0x40 mstore // [] + 0x60 0x00 return // [] + } + + #define macro TIMESTAMP_TO_DATE_WRAPPER() = takes (0) returns (0) { + 0x04 calldataload // [timestamp] + TIMESTAMP_TO_DATE() // [year, month, day] + 0x00 mstore // [month, day] + 0x20 mstore // [day] + 0x40 mstore // [] + 0x60 0x00 return // [] + } + + + + #define macro NTH_WEEKDAY_IN_MONTH_OF_YEAR_TIMESTAMP_WRAPPER() = takes (0) returns (0) { + 0x04 calldataload // [year] + 0x24 calldataload // [month, year] + 0x44 calldataload // [n, month, year] + 0x64 calldataload // [wd, n, month, year] + NTH_WEEKDAY_IN_MONTH_OF_YEAR_TIMESTAMP() // [result] + 0x00 mstore // [] + 0x20 0x00 return // [] + } + +/* Function Dispatcher */ +#define macro MAIN() = takes (0) returns (0) { + // Identify which function is being called. + 0x00 calldataload + + // Extract the function singature + 0xe0 shr + + // Jump table + dup1 __FUNC_SIG(weekday) eq weekday jumpi + dup1 __FUNC_SIG(isLeapYear) eq isLeapYear jumpi + dup1 __FUNC_SIG(daysInMonth) eq daysInMonth jumpi + dup1 __FUNC_SIG(dateToEpochDay) eq dateToEpochDay jumpi + dup1 __FUNC_SIG(epochDayToDate) eq epochDayToDate jumpi + dup1 __FUNC_SIG(timestampToDate) eq timestampToDate jumpi + dup1 __FUNC_SIG(dateToTimestamp) eq dateToTimestamp jumpi + dup1 __FUNC_SIG(dateTimeToTimestamp) eq dateTimeToTimestamp jumpi + dup1 __FUNC_SIG(nthWeekdayInMonthOfYearTimestamp) eq nthWeekdayInMonthOfYearTimestamp jumpi + + + weekday: + WEEKDAY_WRAPPER() + + isLeapYear: + IS_LEAP_YEAR_WRAPPER() + + daysInMonth: + DAYS_IN_MONTH_WRAPPER() + + dateToEpochDay: + DATE_TO_EPOCH_DAY_WRAPPER() + + epochDayToDate: + EPOCH_DAY_TO_DATE_WRAPPER() + + timestampToDate: + TIMESTAMP_TO_DATE_WRAPPER() + + dateToTimestamp: + DATE_TO_TIMESTAMP_WRAPPER() + + dateTimeToTimestamp: + DATE_TIME_TO_TIMESTAMP_WRAPPER() + + nthWeekdayInMonthOfYearTimestamp: + NTH_WEEKDAY_IN_MONTH_OF_YEAR_TIMESTAMP_WRAPPER() + +} + + + + +/// @title DateTimeLib +/// @notice SPDX-License-Identifier: MIT +/// @author PraneshASP +/// @notice Library for date time operations. +/// @notice Adapted from Solady (https://github.com/Vectorized/solady/blob/main/src/utils/DateTimeLib.so) + +/// Conventions: +/// --------------------------------------------------------------------+ +/// Unit | Range | Notes | +/// --------------------------------------------------------------------| +/// timestamp | 0..0x1e18549868c76ff | Unix timestamp. | +/// epochDay | 0..0x16d3e098039 | Days since 1970-01-01. | +/// year | 1970..0xffffffff | Gregorian calendar year. | +/// month | 1..12 | Gregorian calendar month. | +/// day | 1..31 | Gregorian calendar day of month. | +/// weekday | 1..7 | The day of the week (1-indexed). | +/// --------------------------------------------------------------------+ +/// All timestamps of days are rounded down to 00:00:00 UTC. + +//////////////////////////////////////////////////////////////// +// Logic // +//////////////////////////////////////////////////////////////// + +/// @dev Returns day of the week (Monday is indicated as 1 and so on) +#define macro WEEKDAY() = takes (0) returns (0) { + // Formula: ((timestamp / 86400 + 3) % 7) + 1; + + // Input Stack: [timestamp(t)] + + 0x15180 // [86400, t] + swap1 // [t,86400] + div // [t/86400] + 0x03 // [3, t/86400] + add // [3 + t/86400] + 0x07 // [7, (3+t/86400)] + swap1 // [(t/86400 + 3), 7] + mod // [(t/86400 + 3) % 7] + 0x01 // [1, (t/86400 + 3)%7] + add // [1 + (t/86400 + 3)%7] + + // Return stack: [result] +} + +#define macro IS_LEAP_YEAR() = takes (0) returns (0) { + // Condition 1, C1 = year % 4 == 0 + // Condition 2, C2 = year % 100 != 0 + // Condition 3, C3 = year % 400 == 0 + + // Formula: C1 && (C2||C3) + + // Input stack: [year] + + // Calculate C2 + 0x64 // [100, year] + dup2 // [year, 100, year] + mod // [year % 100, year] + iszero // [year % 100 == 0, year] + not // [C2, year] + + // Calculate C1 + 0x04 // [4, C2, year] + dup3 // [year, 4, C2, year] + mod // [year % 4, C2, year] + iszero // [C1, C2, year] + + // Calculate C3 + swap2 // [year, C2, C1] + 0x190 // [400, year, C2, C1] + swap1 // [year, 400, C2, C1] + mod // [year % 400, C2, C1] + iszero // [C3, C2, C1] + or // [(C2||C3), C1] + and // [(C2||C3) && C1] + + // Return stack: [result] +} + + +#define macro DAYS_IN_MONTH() = takes (0) returns (0) { + // Input Stack : [month, year] + + // Push days in month map: [31,28,31,30,31,30,31,31,30,31,30,31] + 0x1F1C1F1E1F1E1F1F1E1F1E1F // [daysInMonthMap, month, year] + + dup2 // [month, daysInMonthMap, month, year] + 0x13 // [19, month, daysInMonthMap, month, year] + add // [monthOffset, daysInMonthMap, month, year] + byte // [daysInMonth, month, year] + swap2 // [year, month, daysInMonth] + IS_LEAP_YEAR() // [isleap(year), month, daysInMonth] + swap1 // [month, isleap(year), daysInMonth] + 0x02 // [2, month, isleap(year), daysInMonth] + eq // [2 == month, isleap(year), daysInMonth] + and // [2==month && isleap(year), daysInMonth] + add // [2==month && isleap(year) + daysInMonth] + + // Return stack: [result] +} + + +#define macro DATE_TO_EPOCH_DAY() = takes (0) returns (0) { + // Input stack : [d, m, y] + swap2 // [y,m,d] + 0x3 // [3,y,m,d] + dup3 // [m,3,y,m,d] + lt // [m < 3, y,m,d] + swap1 // [y, m<3, m,d] + sub // [y-m<3,m,d] + // y = y - (m<3) + /// doy construction + dup3 // [d, y,m,d] + 0x301 // [769,d, y, m, d] + 0xc // [12, 769,d, y, m, d] + 0x9 // [9,12, 769,d, y, m, d] + dup6 // [m, 9,12, 769,d, y, m, d] + add // [m + 9,12, 769, d, y, m, d] + mod // [m + 9 % 12, 769, d, y, m, d] + 0xf4ff // [62719, m + 9 % 12, 769,d, y, m, d] + mul // [62719 * m + 9 % 12, 769, d, y, m, d] + add // [62719 * m + 9 % 12 + 769,d, y, m, d] + 0xb // [11, 62719 * m + 9 % 12 + 769, d, y, m, d] + shr // [62719 * m + 9 % 12 + 769 >> 11, d, y, m, d] + add // [62719 * m + 9 % 12 + 769 >> 11 + d, y, m, d] + // [doy, y,m,d] + + /// yoe construction + 0x190 // [400,doy,y,m,d] + dup3 // [y,400, doy,y,m,d] + mod // [y%400, doy, y, m,d] + // [yoe, doy, y, m, d] + /// doe construction + 0x64 // [100, yoe, doy, y, m, d] + dup2 // [yoe, 100, yoe, doy, y, m, d] + div // [yoe / 100, yoe, doy, y, m, d] + dup3 // [doy, yoe / 100, yoe, doy, y, m, d] + dup3 // [yoe, doy, yoe / 100, yoe, doy, y, m, d] + 0x2 // [2, yoe, doy, yoe / 100, yoe, doy, y, m, d] + shr // [yoe >> 2, doy, yoe / 100, yoe, doy, y, m, d] + 0x16d // [365, yoe >> 2, doy, yoe / 100, yoe, doy, y, m, d] + dup5 // [yoe, 365, yoe >> 2, doy, yoe / 100, yoe, doy, y, m, d] + mul // [yoe * 365, yoe >> 2, doy, yoe / 100, yoe, doy, y, m, d] + add // [yoe * 365 + yoe >> 2, doy, yoe / 100, yoe, doy, y, m, d] + add // [yoe * 365 + yoe >> 2 + doy, yoe / 100, yoe, doy, y, m, d] + sub // [yoe * 365 + yoe >> 2 + doy - yoe / 100, yoe, doy, y, m, d] + // [doe, yoe, doy, y, m, d] + + 0xafa6d // [719469, doe, yoe, doy, y, m, d] + swap1 // [doe, 719469, yoe, doy, y, m, d] + 0x23ab1 // [146097, doe, 719469, yoe, doy, y, m, d] + 0x190 // [400, 146097, doe, 719469, yoe, doy, y, m, d] + dup7 // [y, 400, 146097, doe, 719469, yoe, doy, y, m, d] + div // [y / 400, 146097, doe, 719469, yoe, doy, y, m, d] + mul // [y / 400 * 146097, doe, 719469, yoe, doy, y, m, d] + add // [y / 400 * 146097 + doe, 719469, yoe, doy, y, m, d] + sub // [y / 400 * 146097 + doe - 719469, yoe, doy, y, m, d] + + // Clear stack + swap5 + pop pop pop pop pop + + // Return stack: // [result] +} + +#define macro DATE_TO_TIMESTAMP() = takes (0) returns (0) { + // Input stack = [d, m, y] + DATE_TO_EPOCH_DAY() // [epochDay] + 0x15180 // [86400, epochDay] + mul // [86400 * epochDay] + // Return stack: // [timestamp] +} + + +#define macro NTH_WEEKDAY_IN_MONTH_OF_YEAR_TIMESTAMP() = takes (0) returns (0) { + // Input stack: [wd, n, m, y] + dup4 // [y, wd, n, m, y] + dup4 // [m, y, wd, n, m, y] + 0x1 // [1, m, y, wd, n, m, y] + DATE_TO_EPOCH_DAY() // [d, wd, n, m, y] + + dup5 // [y, d, wd, n, m, y] + dup5 // [m, y, d, wd, n, m, y] + DAYS_IN_MONTH() // [md, d, wd, n, m, y] + + 0x1 // [1, md, d, wd, n, m, y] + 0x7 // [7, 1, md, d, wd, n, m, y] + 0x3 // [3, 7, 1, md, d, wd, n, m, y] + dup5 // [d, 3, 7, 1, md, d, wd, n, m, y] + add // [d + 3, 7, 1, md, d, wd, n, m, y] + mod // [d + 3 % 7, 1, md, d, wd, n, m, y] + add // [d + 3 % 7 + 1, md, d, wd, n, m, y] + dup4 // [wd, d + 3 % 7 + 1, md, d, wd, n, m, y] + sub // [wd - d + 3 % 7 + 1, md, d, wd, n, m, y] + // [diff, md, d, wd, n, m, y] + + 0x7 // [7, diff, md, d, wd, n, m, y] + 0x6 // [6, 7, diff, md, d, wd, n, m, y] + dup3 // [diff, 6, 7, diff, md, d, wd, n, m, y] + gt // [diff > 6, 7, diff, md, d, wd, n, m, y] + mul // [diff > 6 * 7, diff, md, d, wd, n, m, y] + add // [diff > 6 * 7 + diff, md, d, wd, n, m, y] + 0x7 // [7,diff > 6 * 7 + diff, md, d, wd, n, m, y] + 0x1 // [1, 7, diff > 6 * 7 + diff, md, d, wd, n, m, y] + dup7 // [n, 1, 7,diff > 6 * 7 + diff, md, d, wd, n, m, y] + sub // [n - 1, 7,diff > 6 * 7 + diff, md, d, wd, n, m, y] + mul // [n - 1 * 7,diff > 6 * 7 + diff, md, d, wd, n, m, y] + add // [n - 1 * 7 + diff > 6 * 7 + diff, md, d, wd, n, m, y] + // [date, md, d, wd, n, m, y] + + swap4 // [n, md, d, wd, date, m, y] + iszero // [n==0, md, d,wd, date, m, y] + iszero // [((n==0)==0), md, d, wd, date, m, y] + swap1 // [md,((n==0)==0),d,wd, date,m,y] + dup5 // [date, md,((n==0)==0),d,wd, date,m,y] + lt // [date < md,((n==0)==0),d,wd,date,m,y] + and // [date < md && ((n==0)==0),d,wd,date,m,y] + swap1 // [d, date < md && ((n==0)==0),wd, date,m,y] + dup4 // [date, d, date < md && ((n==0)==0),wd, date,m,y] + add // [date + d, date < md && ((n==0)==0),wd,date,m,y] + 0x15180 // [86400, date + d, date < md && ((n==0)==0),wd,date,m,y] + mul // [86400 * date + d, date < md && ((n==0)==0),wd, date,m,y] + mul // [86400 * date + d * date < md && ((n==0)==0),wd,date,m,y] + + // clear stack + swap4 + pop pop + pop pop + + // Return stack: // [result] +} + + + +#define macro DATE_TIME_TO_TIMESTAMP() = takes(0) returns(0) { + // Input stack : [day, month ,year ,hour,min,sec] + + DATE_TO_EPOCH_DAY() // [epochDay, hour, min, sec] + 0x15180 // [86400,epochDay, hour, min, sec] + mul // [86400*epochDay, hour, min, sec] + swap1 // [hour, 86400*epochDay, min, sec] + 0xe10 // [3600,hour, 86400*epochDay, min, sec] + mul // [3600*hour, 86400*epochDay, min, sec] + swap2 // [min, 86400*epochDay, 3600*hour, sec] + 0x3c // [60,min, 86400*epochDay, 3600*hour, sec] + mul // [60 * min, 86400*epochDay, 3600*hour, sec] + add // [60 * min + 86400*epochDay, 3600*hour, sec] + add // [60 * min + 86400*epochDay + 3600*hour, sec] + add // [60 * min + 86400*epochDay + 3600*hour + sec] + + // Return stack: [result] +} + +#define macro GET_DAY() = takes(0) returns(0) { + // Input stack: [mp, doy, yoe, doe, epochDay] + + 0x1 // [1, mp, doy, yoe, doe, epochDay] + 0x301 // [769, 1, mp, doy, yoe, doe, epochDay] + 0xf4ff // [62719, 769, 1, mp, doy, yoe, doe, epochDay] + dup4 // [mp, 62719, 769, 1, mp, doy, yoe, doe, epochDay] + mul // [mp * 62719, 769, 1, mp, doy, yoe, doe, epochDay] + add // [mp * 62719 + 769, 1, mp, doy, yoe, doe, epochDay] + 0xb // [11, mp * 62719 + 769, 1, mp, doy, yoe, doe, epochDay] + shr // [11 >> mp * 62719 + 769, 1, mp, doy, yoe, doe, epochDay] + dup4 // [doy, 11 >> mp * 62719 + 769, 1, mp, doy, yoe, doe, epochDay] + sub // [doy - 11 >> mp * 62719 + 769, 1, mp, doy, yoe, doe, epochDay] + add // [doy - 11 >> mp * 62719 + 769 + 1, mp, doy, yoe, doe, epochDay] + + // Return stack : // [day, mp, doy, yoe, doe, epochDay] +} + +#define macro GET_MONTH() = takes(0) returns(0) { + // Input stack: [day, mp, doy, yoe, doe, epochDay] + + 0xc // [11,day, mp, doy, yoe, doe, epochDay] + 0x9 // [9,11,day, mp, doy, yoe, doe, epochDay] + dup4 // [mp,9,11,day, mp, doy, yoe, doe, epochDay] + gt // [mp > 9,11,day, mp, doy, yoe, doe, epochDay] + mul // [mp > 9 * 11,day, mp, doy, yoe, doe, epochDay] + 0x3 // [3, mp > 9 * 11,day, mp, doy, yoe, doe, epochDay] + dup4 // [mp, 3, mp > 9 * 11,day, mp, doy, yoe, doe, epochDay] + add // [mp + 3, mp > 9 * 11,day, mp, doy, yoe, doe, epochDay] + sub // [mp + 3 - mp > 9 * 11,day, mp, doy, yoe, doe, epochDay] + + // Return stack : // [month, day, mp, doy, yoe, doe, epochDay] +} + +#define macro GET_YEAR() = takes(0) returns(0) { + // Input stack: [month, day, mp, doy, yoe, doe, epochDay] + + 0x3 // [3, month, day, mp, doy, yoe, doe, epochDay] + dup2 // [month, 3, month, day, mp, doy, yoe, doe, epochDay] + lt // [month < 3, month, day, mp, doy, yoe, doe, epochDay] + 0x190 // [400, month < 3, month, day, mp, doy, yoe, doe, epochDay] + 0x23ab1 // [146097,400, month < 3, month, day, mp, doy, yoe, doe, epochDay] + dup10 // [epochDay, 146097,400, month < 3, month, day, mp, doy, yoe, doe, epochDay] + div // [epochDay / 146097, 400, month < 3, month, day, mp, doy, yoe, doe, epochDay] + mul // [epochDay / 146097 * 400, month < 3, month, day, mp, doy, yoe, doe, epochDay] + dup7 // [yoe, epochDay / 146097 * 400, month < 3, month, day, mp, doy, yoe, doe, epochDay] + add // [yoe+ epochDay / 146097 * 400, month < 3, month, day, mp, doy, yoe, doe, epochDay] + add // [yoe+ epochDay / 146097 * 400 + month < 3, month, day, mp, doy, yoe, doe, epochDay] + + // Return stack : // [year, month, day, mp, doy, yoe, doe, epochDay] +} + +#define macro EPOCH_DAY_TO_DATE() = takes(0) returns(0) { + // Input stack : // [epochDay] + + 0xafa6c // [719468, epochDay] + add // [epochDay] + dup1 // [epochDay, epochDay] + 0x23ab1 // [146097, epochDay,epochDay] + swap1 // [epochDay, 146097,epochDay] + mod // [epochDay % 146097,epochDay] + // [doe,epochDay] + + 0x16d // [365, doe, epochDay] + 0x23ab0 // [146096, 365, doe, epochDay] + dup3 // [doe, 146096, 365, doe, epochDay] + eq // [doe == 146096, 365, doe, epochDay] + 0x5b4 // [1460, doe == 146096, 365, doe, epochDay] + dup4 // [doe, 1460, doe == 146096, 365, doe, epochDay] + div // [doe / 1460, doe == 146096, 365, doe, epochDay] + 0x8eac // [36524, doe / 1460, doe == 146096, 365, doe, epochDay] + dup5 // [doe, 36524, doe / 1460, doe == 146096, 365, doe, epochDay] + div // [doe/ 36524, doe / 1460, doe == 146096, 365, doe, epochDay] + dup5 // [doe, doe/ 36524, doe / 1460, doe == 146096, 365, doe, epochDay] + add // [doe + doe/ 36524, doe / 1460, doe == 146096, 365, doe, epochDay] + sub // [doe + doe/ 36524 - doe / 1460, doe == 146096, 365, doe, epochDay] + sub // [doe + doe/ 36524 - doe / 1460 - doe == 146096, 365, doe, epochDay] + div // [doe + doe/ 36524 - doe / 1460 - doe == 146096 / 365, doe, epochDay] + // [yoe, doe, epochDay] + + 0x64 // [100, yoe, doe, epochDay] + dup2 // [yoe, 100, yoe, doe, epochDay] + div // [yoe / 100, yoe, doe, epochDay] + dup2 // [yoe,yoe / 100, yoe, doe, epochDay] + 0x2 // [2, yoe,yoe / 100, yoe, doe, epochDay] + shr // [yoe >> 2,yoe / 100, yoe, doe, epochDay] + dup3 // [yoe, yoe >> 2,yoe / 100, yoe, doe, epochDay] + 0x16d // [365, yoe, yoe >> 2,yoe / 100, yoe, doe, epochDay] + mul // [365 * yoe, yoe >> 2,yoe / 100, yoe, doe, epochDay] + add // [365 * yoe + yoe >> 2,yoe / 100, yoe, doe, epochDay] + sub // [365 * yoe + yoe >> 2 - yoe / 100, yoe, doe, epochDay] + dup3 // [doe,365 * yoe + yoe >> 2 - yoe / 100, yoe, doe, epochDay] + sub // [doe - 365 * yoe + yoe >> 2 - yoe / 100, yoe, doe, epochDay] + // [doy, yoe, doe, epochDay] + 0x99 // [153, doy, yoe, doe, epochDay] + 0x2 // [2, 153, doy, yoe, doe, epochDay] + dup3 // [doy,2, 153, doy, yoe, doe, epochDay] + 0x5 // [5, doy,2, 153, doy, yoe, doe, epochDay] + mul // [5 * doy,2, 153, doy, yoe, doe, epochDay] + add // [5 * doy + 2, 153, doy, yoe, doe, epochDay] + div // [5 * doy + 2 / 153, doy, yoe, doe, epochDay] + // [mp, doy, yoe, doe, epochDay] + + GET_DAY() // [day, mp, doy, yoe, doe, epochDay] + GET_MONTH() // [month, day, mp, doy, yoe, doe, epochDay] + GET_YEAR() // [year, month, day, mp, doy, yoe, doe, epochDay] + +} + +#define macro TIMESTAMP_TO_DATE() = takes(0) returns(0) { + // Imput stack: [timestamp] + + 0x15180 // [86400, timestamp] + swap1 // [timestamp, 86400] + div // [timestamp / 86400] + + EPOCH_DAY_TO_DATE() // [year, month, day] + + // Return stack: [year, month, day] +} diff --git a/src/utils/__TEMP__vqfnwunrsrlqxsbhtmizflbifjcrmxdqCREATE3.huff b/src/utils/__TEMP__vqfnwunrsrlqxsbhtmizflbifjcrmxdqCREATE3.huff new file mode 100644 index 00000000..48b6ccf8 --- /dev/null +++ b/src/utils/__TEMP__vqfnwunrsrlqxsbhtmizflbifjcrmxdqCREATE3.huff @@ -0,0 +1,177 @@ +#define function deploy(bytes32, bytes, uint256) payable returns (address) +#define function getDeployed(bytes32) view returns (address) + +#define macro CREATE_3_DEPLOY_WRAPPER() = takes (0) returns (0) { + 0x44 calldataload // [value] + 0x24 calldataload // [&creationCode, value] + 0x04 calldataload // [salt, &creationCode, value] + CREATE_3_DEPLOY() // [deployed] + 0x00 mstore // [] + 0x20 0x00 return // [] +} + +#define macro CREATE_3_GET_DEPLOYED_WRAPPER() = takes (0) returns (0) { + 0x04 calldataload // [salt] + CREATE_3_GET_DEPLOYED() // [deployed] + 0x00 mstore // [] + 0x20 0x00 return // [] +} + +#define macro MAIN() = { + pc calldataload 0xe0 shr + + dup1 __FUNC_SIG(deploy) eq deploy_jump jumpi + dup1 __FUNC_SIG(getDeployed) eq get_deployed_jump jumpi + + // Exit if selector does not match + 0x00 dup1 revert + + deploy_jump: + CREATE_3_DEPLOY_WRAPPER() + get_deployed_jump: + CREATE_3_GET_DEPLOYED_WRAPPER() +} + +/// @title Create3 +/// @notice SPDX-License-Identifier: MIT +/// @author Maddiaa +/// @author asnared +/// @notice Deploy to deterministic addresses without an initcode factor +/// @notice Adapted from Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/CREATE3.sol) + +#include "./CommonErrors.huff" + + +// Proxy Constants +#define constant PROXY_BYTECODE = 0x67363d3d37363d34f03d5260086018f3 +#define constant PROXY_BYTECODE_HASH = 0x21c35dbe1b344a2488cf3321d6ce542f8e9f305544ff09e4993a62319a497c1f + +//--------------------------------------------------------------------------------// +// Opcode | Opcode + Arguments | Description | Stack View // +//--------------------------------------------------------------------------------// +// 0x36 | 0x36 | CALLDATASIZE | size // +// 0x3d | 0x3d | RETURNDATASIZE | 0 size // +// 0x3d | 0x3d | RETURNDATASIZE | 0 0 size // +// 0x37 | 0x37 | CALLDATACOPY | // +// 0x36 | 0x36 | CALLDATASIZE | size // +// 0x3d | 0x3d | RETURNDATASIZE | 0 size // +// 0x34 | 0x34 | CALLVALUE | value 0 size // +// 0xf0 | 0xf0 | CREATE | newContract // +//--------------------------------------------------------------------------------// +// Opcode | Opcode + Arguments | Description | Stack View // +//--------------------------------------------------------------------------------// +// 0x67 | 0x67XXXXXXXXXXXXXXXX | PUSH8 bytecode | bytecode // +// 0x3d | 0x3d | RETURNDATASIZE | 0 bytecode // +// 0x52 | 0x52 | MSTORE | // +// 0x60 | 0x6008 | PUSH1 08 | 8 // +// 0x60 | 0x6018 | PUSH1 18 | 24 8 // +// 0xf3 | 0xf3 | RETURN | // +//--------------------------------------------------------------------------------// + +/// @notice Deploy a new contract with our pre-made bytecode via CREATE2 +#define macro CREATE_3_DEPLOY() = takes (3) returns (1) { + // Input Stack: [salt, &creationCode, value] + // Output Stack: [deployed] + + // Create the proxy + dup1 0x10 // [size, salt, salt, &creationCode, value] + + // Shift the proxy bytecode left + [PROXY_BYTECODE] // [bytecode, size, salt, salt, &creationCode, value, bytecode] + 0x80 shl // [RIGHTPAD(bytecode), size, salt, salt, &creationCode, value, bytecode] + 0x00 mstore // [size, salt, salt, &creationCode, value] + 0x00 // [offset, size, salt, salt, &creationCode, value] + 0x00 // [value, offset, size, salt, salt, &creationCode, value] + create2 // [address, salt, &creationCode, value] + + // Check the address of of the proxy is not null + dup1 iszero // [address == 0, address, salt, &creationCode, value] + deployment_failed jumpi // [address, salt, &creationCode, value] + + // Load the length of the creation code + dup3 0x04 add calldataload // [creationCode.length, address, salt, &creationCode, value] + + // Copy the code from calldata to memory at memory position 0x20 + dup1 0x05 shl // [size, creationCode.length, address, salt, &creationCode, value] + dup5 0x24 add // [calldataOffset, size, creationCode.length, address, salt, &creationCode, value] + 0x20 // [destOffset, calldataOffset, size, creationCode.length, address, salt, &creationCode, value] + calldatacopy // [creationCode.length, address, salt, &creationCode, value] + + // Call the proxy with the creation code + 0x20 // [retSize, creationCode.length, address, salt, &creationCode, value] + 0x00 // [retOffset, retSize, creationCode.length, address, salt, &creationCode, value] + dup3 // [argSize, retOffset, retSize, creationCode.length, address, salt, &creationCode, value] + 0x20 // [argOffset, argSize, retOffset, retSize, creationCode.length, address, salt, &creationCode, value] + dup9 // [value, argOffset, argSize, retOffset, retSize, creationCode.length, address, salt, &creationCode, value] + dup7 // [to, value, argOffset, argSize, retOffset, retSize, creationCode.length, address, salt, &creationCode, value] + gas // [gas, to, value, argOffset, argSize, retOffset, retSize, creationCode.length, address, salt, &creationCode, value] + call // [success, creationCode.length, address, salt, &creationCode, value] + iszero // [success == 0, creationCode.length, address, salt, &creationCode, value] + init_failed jumpi // [creationCode.length, address, salt, &creationCode, value] + + // Get the deployed contract using the salt and make sure it has code at the address + dup3 CREATE_3_GET_DEPLOYED() // [deployed, creationCode.length, address, salt, &creationCode, value] + dup1 extcodesize // [deployed == 0, deployed, creationCode.length, address, salt, &creationCode, value] + iszero init_failed jumpi // [deployed, creationCode.length, address, salt, &creationCode, value] + + // Clean up stack and return + swap5 pop pop pop pop pop // [deployed] + done jump + + deployment_failed: + DEPLOYMENT_FAILED(0x00) + init_failed: + INITIALIZATION_FAILED(0x00) + + done: +} + +#define macro CREATE_3_GET_DEPLOYED() = takes (1) returns (1) { + // Input Stack : [salt] + // Output Stack: [deployed_address] + + // Store 0xff | (right_padded_address >> 1) in memory + __RIGHTPAD(0xff) // [rightpad(0xff), salt] + address 0x58 shl // [rightpad(address), rightpad(0xff), salt] + or // [[0xff][address], salt] + 0x00 mstore // [salt] + + // Store the salt in memory at position 0x15 + 0x15 mstore // [] + + // Store the hash in memory at 0x35 + [PROXY_BYTECODE_HASH] // [hash] + 0x35 mstore // [] + + // Hash the memory from 0x00:0x55 + 0x55 0x00 sha3 // [keccak] + + // ---------------------------------------- // + // Memory Layout // + // ---------------------------------------- // + // prefix | address | nonce | empty // + // 0xd694 | | 01 | 000..000 // + // ---------------------------------------- // + + // 0xd6 = 0xc0 (short RLP prefix) + 0x16 (length of: 0x94 ++ proxy ++ 0x01) + // 0x94 = 0x80 + 0x14 (0x14 = the length of an address, 20 bytes, in hex) + + // Clear the top 10 bytes of the hash + 0x60 shl 0x10 shr // [proxy_address] + + // return rpl encoded + __RIGHTPAD(0xd694) // [0xd694, proxy_address] + or // [ [0xd694][proxy_address] ] + + // Append a 0x01 to the end of the address + + 0x01 0x48 shl // [0x01 << 9, [0xd694][proxy_address]] + or // [ [0xd694][proxy_address][01] ] + + // Hash the packed encoding in memory position 0x00 + 0x00 mstore // [] + 0x17 0x00 sha3 // [hash] + + // Clear the top 12 bytes using shifts + 0x60 shl 0x60 shr // [proxy_address] +} diff --git a/src/utils/__TEMP__wiecgaaxwkphsyuihxlbouwaxpbkeiagInsertionSort.huff b/src/utils/__TEMP__wiecgaaxwkphsyuihxlbouwaxpbkeiagInsertionSort.huff new file mode 100644 index 00000000..2959ef82 --- /dev/null +++ b/src/utils/__TEMP__wiecgaaxwkphsyuihxlbouwaxpbkeiagInsertionSort.huff @@ -0,0 +1,100 @@ +/// SPDX-License-Identifier: MIT + +/// @notice Insertion Sort Function +#define function insertionSort(uint256[]) nonpayable returns (uint256[]) + +/// @notice Performs insertion sort on raw calldata +#define macro INSERTION_SORT() = takes (0) returns (0) { + SORT() // [offset, arrSize] + return // [] +} + +/// @notice The contract entrypoint +#define macro MAIN() = takes(0) returns (0) { + returndatasize calldataload 0xe0 shr // [selector] + + // notice: we don't need to duplicate the selector here + // since the selector is consumed and only used once + __FUNC_SIG(insertionSort) eq jumpSort jumpi // [] + + // Reverts if selector not present. + returndatasize returndatasize revert + + jumpSort: + INSERTION_SORT() +} + + +/// @title Sort +/// @notice SPDX-License-Identifier: MIT +/// @author tanim0la +/// @notice Insertion sort implementation + +/* MACRO */ +/// @notice Returns two items `offSet` and `arrSize` +#define macro SORT() = takes (0) returns (2) { + + 0x04 calldatasize sub // [arrSize] + dup1 // [arrSize, arrSize] + 0x04 // [offset, arrSize, arrSize] + 0x40 // [mem, offset, arrSize, arrSize] + calldatacopy // [arrSize] + + 0x01 returndatasize mstore // i = 1 + 0x60 mload // [len, arrSize] + + // For loop + start: + // End if i == len + returndatasize mload // [i, len, arrSize] + dup2 dup2 // [i, len, i, len, arrSize] + eq end jumpi + + // Assign i to j + 0x20 mstore // [len, arrSize] + + // While loop + while: + returndatasize // [0, len, arrSize] + 0x20 mload dup2 dup2 // [j, 0, j, 0, len, arrSize] + gt // [cndt1, j, 0, len, arrSize] + + + // 0x80 + (0x20 * j) + dup2 0x20 mul 0x80 add // [mem[arr[j]], cndt1, j, 0, len, arrSize] + + // 0x80 + (0x20 * (j - 0x01)) + 0x01 dup4 sub 0x20 mul 0x80 add // [mem[arr[j - i]], mem[arr[j]], cndt1, j, 0, len, arrSize] + dup2 // [mem[arr[j]], mem[arr[j - 1]], mem[arr[j]], cndt1, j, 0, len, arrSize] + + mload // [arr[j], mem[arr[j - 1]], mem[arr[j]], cndt1, j, 0, len, arrSize] + dup2 mload // [arr[j - 1], arr[j], mem[arr[j - 1]], mem[arr[j]], cndt1, j, 0, len, arrSize] + + gt dup4 // [cndt1, cndt2, mem[arr[j - 1]], mem[arr[j]], cndt1, j, 0, len, arrSize] + and continueWhile jumpi // [mem[arr[j - 1]], mem[arr[j]], cndt1, j, 0, len, arrSize] + + // Go to continue + pop pop pop pop pop // [len, arrSize] + + // Increment i++ + returndatasize mload 0x01 add // [i + 1, len, arrSize] + returndatasize mstore start jump // [len, arrSize] + + // While block + continueWhile: + // arr[j - 1] = arr[j] + dup1 mload dup3 mload // [arr[j], arr[j - i], mem[arr[j - 1]], mem[arr[j]], cndt1, j, 0, len, arrSize] + dup3 mstore // [arr[j - 1], mem[arr[j - 1]], mem[arr[j]], cndt1, j, 0, len, arrSize] + + // arr[j] = arr[j - 1] + dup3 mstore // [mem[arr[j - 1], mem[arr[j]], cndt1, j, 0, len, arrSize] + + pop pop pop // [j, 0, len, arrSize] + + // Decrement j-- + 0x01 dup2 sub // [j - 1 ,j, 0, len, arrSize] + 0x20 mstore pop pop // [len, arrSize] + while jump + end: + pop pop 0x40 // [offset, arrSize] +} diff --git a/src/utils/__TEMP__wtgpdnpvqgkfupsuzejejufgqepcfpeyDateTimeLib.huff b/src/utils/__TEMP__wtgpdnpvqgkfupsuzejejufgqepcfpeyDateTimeLib.huff new file mode 100644 index 00000000..04bae5ed --- /dev/null +++ b/src/utils/__TEMP__wtgpdnpvqgkfupsuzejejufgqepcfpeyDateTimeLib.huff @@ -0,0 +1,517 @@ +/* Functions */ +#define function weekday(uint256) nonpayable returns (uint256) +#define function isLeapYear(uint256) nonpayable returns (bool) +#define function daysInMonth(uint256,uint256) nonpayable returns (uint256) +#define function dateToEpochDay(uint256,uint256,uint256) nonpayable returns (uint256) +#define function dateToTimestamp(uint256,uint256,uint256) nonpayable returns (uint256) +#define function dateTimeToTimestamp(uint256,uint256,uint256,uint256,uint256,uint256) nonpayable returns (uint256) +#define function nthWeekdayInMonthOfYearTimestamp(uint256, uint256,uint256,uint256) nonpayable returns (uint256) +#define function epochDayToDate(uint256) nonpayable returns (uint256,uint256,uint256) +#define function timestampToDate(uint256) nonpayable returns (uint256,uint256,uint256) + +/* Wrapper Macros */ +#define macro WEEKDAY_WRAPPER() = takes (0) returns (0) { + 0x04 calldataload // [timestamp] + WEEKDAY() // [result] + 0x00 mstore // [] + 0x20 0x00 return // [] + } + +#define macro IS_LEAP_YEAR_WRAPPER() = takes (0) returns (0) { + 0x04 calldataload // [timestamp] + IS_LEAP_YEAR() // [result] + 0x00 mstore // [] + 0x20 0x00 return // [] + } + +#define macro DAYS_IN_MONTH_WRAPPER() = takes (0) returns (0) { + 0x04 calldataload // [year] + 0x24 calldataload // [month, year] + DAYS_IN_MONTH() // [result] + 0x00 mstore // [] + 0x20 0x00 return // [] + } + +#define macro DATE_TO_EPOCH_DAY_WRAPPER() = takes (0) returns (0) { + 0x04 calldataload // [year] + 0x24 calldataload // [month, year] + 0x44 calldataload // [day, month, year] + DATE_TO_EPOCH_DAY() // [result] + 0x00 mstore // [] + 0x20 0x00 return // [] + } + + #define macro DATE_TO_TIMESTAMP_WRAPPER() = takes (0) returns (0) { + 0x04 calldataload // [year] + 0x24 calldataload // [month, year] + 0x44 calldataload // [day, month, year] + DATE_TO_TIMESTAMP() // [result] + 0x00 mstore // [] + 0x20 0x00 return // [] + } + + #define macro DATE_TIME_TO_TIMESTAMP_WRAPPER() = takes (0) returns (0) { + 0x04 calldataload // [year] + 0x24 calldataload // [month, year] + 0x44 calldataload // [day, month, year] + 0x64 calldataload // [seconds, day, month, year] + 0x84 calldataload // [minutes, seconds, day, month, year] + 0xa4 calldataload // [hours, minutes, seconds, day, month, year] + DATE_TIME_TO_TIMESTAMP() // [result] + 0x00 mstore // [] + 0x20 0x00 return // [] + } + + #define macro EPOCH_DAY_TO_DATE_WRAPPER() = takes (0) returns (0) { + 0x04 calldataload // [epochDay] + EPOCH_DAY_TO_DATE() // [year, month, day] + 0x00 mstore // [month, day] + 0x20 mstore // [day] + 0x40 mstore // [] + 0x60 0x00 return // [] + } + + #define macro TIMESTAMP_TO_DATE_WRAPPER() = takes (0) returns (0) { + 0x04 calldataload // [timestamp] + TIMESTAMP_TO_DATE() // [year, month, day] + 0x00 mstore // [month, day] + 0x20 mstore // [day] + 0x40 mstore // [] + 0x60 0x00 return // [] + } + + + + #define macro NTH_WEEKDAY_IN_MONTH_OF_YEAR_TIMESTAMP_WRAPPER() = takes (0) returns (0) { + 0x04 calldataload // [year] + 0x24 calldataload // [month, year] + 0x44 calldataload // [n, month, year] + 0x64 calldataload // [wd, n, month, year] + NTH_WEEKDAY_IN_MONTH_OF_YEAR_TIMESTAMP() // [result] + 0x00 mstore // [] + 0x20 0x00 return // [] + } + +/* Function Dispatcher */ +#define macro MAIN() = takes (0) returns (0) { + // Identify which function is being called. + 0x00 calldataload + + // Extract the function singature + 0xe0 shr + + // Jump table + dup1 __FUNC_SIG(weekday) eq weekday jumpi + dup1 __FUNC_SIG(isLeapYear) eq isLeapYear jumpi + dup1 __FUNC_SIG(daysInMonth) eq daysInMonth jumpi + dup1 __FUNC_SIG(dateToEpochDay) eq dateToEpochDay jumpi + dup1 __FUNC_SIG(epochDayToDate) eq epochDayToDate jumpi + dup1 __FUNC_SIG(timestampToDate) eq timestampToDate jumpi + dup1 __FUNC_SIG(dateToTimestamp) eq dateToTimestamp jumpi + dup1 __FUNC_SIG(dateTimeToTimestamp) eq dateTimeToTimestamp jumpi + dup1 __FUNC_SIG(nthWeekdayInMonthOfYearTimestamp) eq nthWeekdayInMonthOfYearTimestamp jumpi + + + weekday: + WEEKDAY_WRAPPER() + + isLeapYear: + IS_LEAP_YEAR_WRAPPER() + + daysInMonth: + DAYS_IN_MONTH_WRAPPER() + + dateToEpochDay: + DATE_TO_EPOCH_DAY_WRAPPER() + + epochDayToDate: + EPOCH_DAY_TO_DATE_WRAPPER() + + timestampToDate: + TIMESTAMP_TO_DATE_WRAPPER() + + dateToTimestamp: + DATE_TO_TIMESTAMP_WRAPPER() + + dateTimeToTimestamp: + DATE_TIME_TO_TIMESTAMP_WRAPPER() + + nthWeekdayInMonthOfYearTimestamp: + NTH_WEEKDAY_IN_MONTH_OF_YEAR_TIMESTAMP_WRAPPER() + +} + + + + +/// @title DateTimeLib +/// @notice SPDX-License-Identifier: MIT +/// @author PraneshASP +/// @notice Library for date time operations. +/// @notice Adapted from Solady (https://github.com/Vectorized/solady/blob/main/src/utils/DateTimeLib.so) + +/// Conventions: +/// --------------------------------------------------------------------+ +/// Unit | Range | Notes | +/// --------------------------------------------------------------------| +/// timestamp | 0..0x1e18549868c76ff | Unix timestamp. | +/// epochDay | 0..0x16d3e098039 | Days since 1970-01-01. | +/// year | 1970..0xffffffff | Gregorian calendar year. | +/// month | 1..12 | Gregorian calendar month. | +/// day | 1..31 | Gregorian calendar day of month. | +/// weekday | 1..7 | The day of the week (1-indexed). | +/// --------------------------------------------------------------------+ +/// All timestamps of days are rounded down to 00:00:00 UTC. + +//////////////////////////////////////////////////////////////// +// Logic // +//////////////////////////////////////////////////////////////// + +/// @dev Returns day of the week (Monday is indicated as 1 and so on) +#define macro WEEKDAY() = takes (0) returns (0) { + // Formula: ((timestamp / 86400 + 3) % 7) + 1; + + // Input Stack: [timestamp(t)] + + 0x15180 // [86400, t] + swap1 // [t,86400] + div // [t/86400] + 0x03 // [3, t/86400] + add // [3 + t/86400] + 0x07 // [7, (3+t/86400)] + swap1 // [(t/86400 + 3), 7] + mod // [(t/86400 + 3) % 7] + 0x01 // [1, (t/86400 + 3)%7] + add // [1 + (t/86400 + 3)%7] + + // Return stack: [result] +} + +#define macro IS_LEAP_YEAR() = takes (0) returns (0) { + // Condition 1, C1 = year % 4 == 0 + // Condition 2, C2 = year % 100 != 0 + // Condition 3, C3 = year % 400 == 0 + + // Formula: C1 && (C2||C3) + + // Input stack: [year] + + // Calculate C2 + 0x64 // [100, year] + dup2 // [year, 100, year] + mod // [year % 100, year] + iszero // [year % 100 == 0, year] + not // [C2, year] + + // Calculate C1 + 0x04 // [4, C2, year] + dup3 // [year, 4, C2, year] + mod // [year % 4, C2, year] + iszero // [C1, C2, year] + + // Calculate C3 + swap2 // [year, C2, C1] + 0x190 // [400, year, C2, C1] + swap1 // [year, 400, C2, C1] + mod // [year % 400, C2, C1] + iszero // [C3, C2, C1] + or // [(C2||C3), C1] + and // [(C2||C3) && C1] + + // Return stack: [result] +} + + +#define macro DAYS_IN_MONTH() = takes (0) returns (0) { + // Input Stack : [month, year] + + // Push days in month map: [31,28,31,30,31,30,31,31,30,31,30,31] + 0x1F1C1F1E1F1E1F1F1E1F1E1F // [daysInMonthMap, month, year] + + dup2 // [month, daysInMonthMap, month, year] + 0x13 // [19, month, daysInMonthMap, month, year] + add // [monthOffset, daysInMonthMap, month, year] + byte // [daysInMonth, month, year] + swap2 // [year, month, daysInMonth] + IS_LEAP_YEAR() // [isleap(year), month, daysInMonth] + swap1 // [month, isleap(year), daysInMonth] + 0x02 // [2, month, isleap(year), daysInMonth] + eq // [2 == month, isleap(year), daysInMonth] + and // [2==month && isleap(year), daysInMonth] + add // [2==month && isleap(year) + daysInMonth] + + // Return stack: [result] +} + + +#define macro DATE_TO_EPOCH_DAY() = takes (0) returns (0) { + // Input stack : [d, m, y] + swap2 // [y,m,d] + 0x3 // [3,y,m,d] + dup3 // [m,3,y,m,d] + lt // [m < 3, y,m,d] + swap1 // [y, m<3, m,d] + sub // [y-m<3,m,d] + // y = y - (m<3) + /// doy construction + dup3 // [d, y,m,d] + 0x301 // [769,d, y, m, d] + 0xc // [12, 769,d, y, m, d] + 0x9 // [9,12, 769,d, y, m, d] + dup6 // [m, 9,12, 769,d, y, m, d] + add // [m + 9,12, 769, d, y, m, d] + mod // [m + 9 % 12, 769, d, y, m, d] + 0xf4ff // [62719, m + 9 % 12, 769,d, y, m, d] + mul // [62719 * m + 9 % 12, 769, d, y, m, d] + add // [62719 * m + 9 % 12 + 769,d, y, m, d] + 0xb // [11, 62719 * m + 9 % 12 + 769, d, y, m, d] + shr // [62719 * m + 9 % 12 + 769 >> 11, d, y, m, d] + add // [62719 * m + 9 % 12 + 769 >> 11 + d, y, m, d] + // [doy, y,m,d] + + /// yoe construction + 0x190 // [400,doy,y,m,d] + dup3 // [y,400, doy,y,m,d] + mod // [y%400, doy, y, m,d] + // [yoe, doy, y, m, d] + /// doe construction + 0x64 // [100, yoe, doy, y, m, d] + dup2 // [yoe, 100, yoe, doy, y, m, d] + div // [yoe / 100, yoe, doy, y, m, d] + dup3 // [doy, yoe / 100, yoe, doy, y, m, d] + dup3 // [yoe, doy, yoe / 100, yoe, doy, y, m, d] + 0x2 // [2, yoe, doy, yoe / 100, yoe, doy, y, m, d] + shr // [yoe >> 2, doy, yoe / 100, yoe, doy, y, m, d] + 0x16d // [365, yoe >> 2, doy, yoe / 100, yoe, doy, y, m, d] + dup5 // [yoe, 365, yoe >> 2, doy, yoe / 100, yoe, doy, y, m, d] + mul // [yoe * 365, yoe >> 2, doy, yoe / 100, yoe, doy, y, m, d] + add // [yoe * 365 + yoe >> 2, doy, yoe / 100, yoe, doy, y, m, d] + add // [yoe * 365 + yoe >> 2 + doy, yoe / 100, yoe, doy, y, m, d] + sub // [yoe * 365 + yoe >> 2 + doy - yoe / 100, yoe, doy, y, m, d] + // [doe, yoe, doy, y, m, d] + + 0xafa6d // [719469, doe, yoe, doy, y, m, d] + swap1 // [doe, 719469, yoe, doy, y, m, d] + 0x23ab1 // [146097, doe, 719469, yoe, doy, y, m, d] + 0x190 // [400, 146097, doe, 719469, yoe, doy, y, m, d] + dup7 // [y, 400, 146097, doe, 719469, yoe, doy, y, m, d] + div // [y / 400, 146097, doe, 719469, yoe, doy, y, m, d] + mul // [y / 400 * 146097, doe, 719469, yoe, doy, y, m, d] + add // [y / 400 * 146097 + doe, 719469, yoe, doy, y, m, d] + sub // [y / 400 * 146097 + doe - 719469, yoe, doy, y, m, d] + + // Clear stack + swap5 + pop pop pop pop pop + + // Return stack: // [result] +} + +#define macro DATE_TO_TIMESTAMP() = takes (0) returns (0) { + // Input stack = [d, m, y] + DATE_TO_EPOCH_DAY() // [epochDay] + 0x15180 // [86400, epochDay] + mul // [86400 * epochDay] + // Return stack: // [timestamp] +} + + +#define macro NTH_WEEKDAY_IN_MONTH_OF_YEAR_TIMESTAMP() = takes (0) returns (0) { + // Input stack: [wd, n, m, y] + dup4 // [y, wd, n, m, y] + dup4 // [m, y, wd, n, m, y] + 0x1 // [1, m, y, wd, n, m, y] + DATE_TO_EPOCH_DAY() // [d, wd, n, m, y] + + dup5 // [y, d, wd, n, m, y] + dup5 // [m, y, d, wd, n, m, y] + DAYS_IN_MONTH() // [md, d, wd, n, m, y] + + 0x1 // [1, md, d, wd, n, m, y] + 0x7 // [7, 1, md, d, wd, n, m, y] + 0x3 // [3, 7, 1, md, d, wd, n, m, y] + dup5 // [d, 3, 7, 1, md, d, wd, n, m, y] + add // [d + 3, 7, 1, md, d, wd, n, m, y] + mod // [d + 3 % 7, 1, md, d, wd, n, m, y] + add // [d + 3 % 7 + 1, md, d, wd, n, m, y] + dup4 // [wd, d + 3 % 7 + 1, md, d, wd, n, m, y] + sub // [wd - d + 3 % 7 + 1, md, d, wd, n, m, y] + // [diff, md, d, wd, n, m, y] + + 0x7 // [7, diff, md, d, wd, n, m, y] + 0x6 // [6, 7, diff, md, d, wd, n, m, y] + dup3 // [diff, 6, 7, diff, md, d, wd, n, m, y] + gt // [diff > 6, 7, diff, md, d, wd, n, m, y] + mul // [diff > 6 * 7, diff, md, d, wd, n, m, y] + add // [diff > 6 * 7 + diff, md, d, wd, n, m, y] + 0x7 // [7,diff > 6 * 7 + diff, md, d, wd, n, m, y] + 0x1 // [1, 7, diff > 6 * 7 + diff, md, d, wd, n, m, y] + dup7 // [n, 1, 7,diff > 6 * 7 + diff, md, d, wd, n, m, y] + sub // [n - 1, 7,diff > 6 * 7 + diff, md, d, wd, n, m, y] + mul // [n - 1 * 7,diff > 6 * 7 + diff, md, d, wd, n, m, y] + add // [n - 1 * 7 + diff > 6 * 7 + diff, md, d, wd, n, m, y] + // [date, md, d, wd, n, m, y] + + swap4 // [n, md, d, wd, date, m, y] + iszero // [n==0, md, d,wd, date, m, y] + iszero // [((n==0)==0), md, d, wd, date, m, y] + swap1 // [md,((n==0)==0),d,wd, date,m,y] + dup5 // [date, md,((n==0)==0),d,wd, date,m,y] + lt // [date < md,((n==0)==0),d,wd,date,m,y] + and // [date < md && ((n==0)==0),d,wd,date,m,y] + swap1 // [d, date < md && ((n==0)==0),wd, date,m,y] + dup4 // [date, d, date < md && ((n==0)==0),wd, date,m,y] + add // [date + d, date < md && ((n==0)==0),wd,date,m,y] + 0x15180 // [86400, date + d, date < md && ((n==0)==0),wd,date,m,y] + mul // [86400 * date + d, date < md && ((n==0)==0),wd, date,m,y] + mul // [86400 * date + d * date < md && ((n==0)==0),wd,date,m,y] + + // clear stack + swap4 + pop pop + pop pop + + // Return stack: // [result] +} + + + +#define macro DATE_TIME_TO_TIMESTAMP() = takes(0) returns(0) { + // Input stack : [day, month ,year ,hour,min,sec] + + DATE_TO_EPOCH_DAY() // [epochDay, hour, min, sec] + 0x15180 // [86400,epochDay, hour, min, sec] + mul // [86400*epochDay, hour, min, sec] + swap1 // [hour, 86400*epochDay, min, sec] + 0xe10 // [3600,hour, 86400*epochDay, min, sec] + mul // [3600*hour, 86400*epochDay, min, sec] + swap2 // [min, 86400*epochDay, 3600*hour, sec] + 0x3c // [60,min, 86400*epochDay, 3600*hour, sec] + mul // [60 * min, 86400*epochDay, 3600*hour, sec] + add // [60 * min + 86400*epochDay, 3600*hour, sec] + add // [60 * min + 86400*epochDay + 3600*hour, sec] + add // [60 * min + 86400*epochDay + 3600*hour + sec] + + // Return stack: [result] +} + +#define macro GET_DAY() = takes(0) returns(0) { + // Input stack: [mp, doy, yoe, doe, epochDay] + + 0x1 // [1, mp, doy, yoe, doe, epochDay] + 0x301 // [769, 1, mp, doy, yoe, doe, epochDay] + 0xf4ff // [62719, 769, 1, mp, doy, yoe, doe, epochDay] + dup4 // [mp, 62719, 769, 1, mp, doy, yoe, doe, epochDay] + mul // [mp * 62719, 769, 1, mp, doy, yoe, doe, epochDay] + add // [mp * 62719 + 769, 1, mp, doy, yoe, doe, epochDay] + 0xb // [11, mp * 62719 + 769, 1, mp, doy, yoe, doe, epochDay] + shr // [11 >> mp * 62719 + 769, 1, mp, doy, yoe, doe, epochDay] + dup4 // [doy, 11 >> mp * 62719 + 769, 1, mp, doy, yoe, doe, epochDay] + sub // [doy - 11 >> mp * 62719 + 769, 1, mp, doy, yoe, doe, epochDay] + add // [doy - 11 >> mp * 62719 + 769 + 1, mp, doy, yoe, doe, epochDay] + + // Return stack : // [day, mp, doy, yoe, doe, epochDay] +} + +#define macro GET_MONTH() = takes(0) returns(0) { + // Input stack: [day, mp, doy, yoe, doe, epochDay] + + 0xc // [11,day, mp, doy, yoe, doe, epochDay] + 0x9 // [9,11,day, mp, doy, yoe, doe, epochDay] + dup4 // [mp,9,11,day, mp, doy, yoe, doe, epochDay] + gt // [mp > 9,11,day, mp, doy, yoe, doe, epochDay] + mul // [mp > 9 * 11,day, mp, doy, yoe, doe, epochDay] + 0x3 // [3, mp > 9 * 11,day, mp, doy, yoe, doe, epochDay] + dup4 // [mp, 3, mp > 9 * 11,day, mp, doy, yoe, doe, epochDay] + add // [mp + 3, mp > 9 * 11,day, mp, doy, yoe, doe, epochDay] + sub // [mp + 3 - mp > 9 * 11,day, mp, doy, yoe, doe, epochDay] + + // Return stack : // [month, day, mp, doy, yoe, doe, epochDay] +} + +#define macro GET_YEAR() = takes(0) returns(0) { + // Input stack: [month, day, mp, doy, yoe, doe, epochDay] + + 0x3 // [3, month, day, mp, doy, yoe, doe, epochDay] + dup2 // [month, 3, month, day, mp, doy, yoe, doe, epochDay] + lt // [month < 3, month, day, mp, doy, yoe, doe, epochDay] + 0x190 // [400, month < 3, month, day, mp, doy, yoe, doe, epochDay] + 0x23ab1 // [146097,400, month < 3, month, day, mp, doy, yoe, doe, epochDay] + dup10 // [epochDay, 146097,400, month < 3, month, day, mp, doy, yoe, doe, epochDay] + div // [epochDay / 146097, 400, month < 3, month, day, mp, doy, yoe, doe, epochDay] + mul // [epochDay / 146097 * 400, month < 3, month, day, mp, doy, yoe, doe, epochDay] + dup7 // [yoe, epochDay / 146097 * 400, month < 3, month, day, mp, doy, yoe, doe, epochDay] + add // [yoe+ epochDay / 146097 * 400, month < 3, month, day, mp, doy, yoe, doe, epochDay] + add // [yoe+ epochDay / 146097 * 400 + month < 3, month, day, mp, doy, yoe, doe, epochDay] + + // Return stack : // [year, month, day, mp, doy, yoe, doe, epochDay] +} + +#define macro EPOCH_DAY_TO_DATE() = takes(0) returns(0) { + // Input stack : // [epochDay] + + 0xafa6c // [719468, epochDay] + add // [epochDay] + dup1 // [epochDay, epochDay] + 0x23ab1 // [146097, epochDay,epochDay] + swap1 // [epochDay, 146097,epochDay] + mod // [epochDay % 146097,epochDay] + // [doe,epochDay] + + 0x16d // [365, doe, epochDay] + 0x23ab0 // [146096, 365, doe, epochDay] + dup3 // [doe, 146096, 365, doe, epochDay] + eq // [doe == 146096, 365, doe, epochDay] + 0x5b4 // [1460, doe == 146096, 365, doe, epochDay] + dup4 // [doe, 1460, doe == 146096, 365, doe, epochDay] + div // [doe / 1460, doe == 146096, 365, doe, epochDay] + 0x8eac // [36524, doe / 1460, doe == 146096, 365, doe, epochDay] + dup5 // [doe, 36524, doe / 1460, doe == 146096, 365, doe, epochDay] + div // [doe/ 36524, doe / 1460, doe == 146096, 365, doe, epochDay] + dup5 // [doe, doe/ 36524, doe / 1460, doe == 146096, 365, doe, epochDay] + add // [doe + doe/ 36524, doe / 1460, doe == 146096, 365, doe, epochDay] + sub // [doe + doe/ 36524 - doe / 1460, doe == 146096, 365, doe, epochDay] + sub // [doe + doe/ 36524 - doe / 1460 - doe == 146096, 365, doe, epochDay] + div // [doe + doe/ 36524 - doe / 1460 - doe == 146096 / 365, doe, epochDay] + // [yoe, doe, epochDay] + + 0x64 // [100, yoe, doe, epochDay] + dup2 // [yoe, 100, yoe, doe, epochDay] + div // [yoe / 100, yoe, doe, epochDay] + dup2 // [yoe,yoe / 100, yoe, doe, epochDay] + 0x2 // [2, yoe,yoe / 100, yoe, doe, epochDay] + shr // [yoe >> 2,yoe / 100, yoe, doe, epochDay] + dup3 // [yoe, yoe >> 2,yoe / 100, yoe, doe, epochDay] + 0x16d // [365, yoe, yoe >> 2,yoe / 100, yoe, doe, epochDay] + mul // [365 * yoe, yoe >> 2,yoe / 100, yoe, doe, epochDay] + add // [365 * yoe + yoe >> 2,yoe / 100, yoe, doe, epochDay] + sub // [365 * yoe + yoe >> 2 - yoe / 100, yoe, doe, epochDay] + dup3 // [doe,365 * yoe + yoe >> 2 - yoe / 100, yoe, doe, epochDay] + sub // [doe - 365 * yoe + yoe >> 2 - yoe / 100, yoe, doe, epochDay] + // [doy, yoe, doe, epochDay] + 0x99 // [153, doy, yoe, doe, epochDay] + 0x2 // [2, 153, doy, yoe, doe, epochDay] + dup3 // [doy,2, 153, doy, yoe, doe, epochDay] + 0x5 // [5, doy,2, 153, doy, yoe, doe, epochDay] + mul // [5 * doy,2, 153, doy, yoe, doe, epochDay] + add // [5 * doy + 2, 153, doy, yoe, doe, epochDay] + div // [5 * doy + 2 / 153, doy, yoe, doe, epochDay] + // [mp, doy, yoe, doe, epochDay] + + GET_DAY() // [day, mp, doy, yoe, doe, epochDay] + GET_MONTH() // [month, day, mp, doy, yoe, doe, epochDay] + GET_YEAR() // [year, month, day, mp, doy, yoe, doe, epochDay] + +} + +#define macro TIMESTAMP_TO_DATE() = takes(0) returns(0) { + // Imput stack: [timestamp] + + 0x15180 // [86400, timestamp] + swap1 // [timestamp, 86400] + div // [timestamp / 86400] + + EPOCH_DAY_TO_DATE() // [year, month, day] + + // Return stack: [year, month, day] +} diff --git a/src/utils/__TEMP__xllvhpaiggcjojltrdelmvtrrnvpcuusPausable.huff b/src/utils/__TEMP__xllvhpaiggcjojltrdelmvtrrnvpcuusPausable.huff new file mode 100644 index 00000000..9a967559 --- /dev/null +++ b/src/utils/__TEMP__xllvhpaiggcjojltrdelmvtrrnvpcuusPausable.huff @@ -0,0 +1,131 @@ +#define function isPaused() view returns (bool) +#define function pause() nonpayable returns () +#define function unpause() nonpayable returns () + + +#define macro CONSTRUCTOR() = takes (0) returns (0) { + PAUSABLE_CONSTRUCTOR() +} + + +#define macro IS_PAUSED_WRAPPER() = takes (0) returns (0) { + PAUSABLE_IS_PAUSED() +} + +#define macro PAUSE_WRAPPER() = takes (0) returns (0) { + PAUSABLE_PAUSE() +} + +#define macro UNPAUSE_WRAPPER() = takes (0) returns (0) { + PAUSABLE_UNPAUSE() +} + + +#define macro MAIN() = takes (0) returns (0) { + pc calldataload 0xe0 shr // [sig] + + dup1 __FUNC_SIG(pause) eq pause jumpi + dup1 __FUNC_SIG(unpause) eq unpause jumpi + dup1 __FUNC_SIG(isPaused) eq is_paused jumpi + + 0x00 dup1 revert + + pause: + PAUSE_WRAPPER() + unpause: + UNPAUSE_WRAPPER() + is_paused: + IS_PAUSED_WRAPPER() +} + +/// @title Pausable +/// @notice SPDX-License-Identifier: MIT +/// @author zarf.eth +/// @notice A Pausable implementation + + +// Interface + +/// @notice returns whether the contract is paused +#define function isPaused() view returns (bool) + +/// @notice Pauses the contract +/// @dev Only callable when the contract is unpaused. +#define function pause() nonpayable returns () + +/// @notice Unpauses the contract +/// @dev Only callable when the contract is paused. +#define function unpause() nonpayable returns () + +/// @notice Emitted when contract is paused. +#define event Paused(address) + +/// @notice Emitted when contract is unpaused. +#define event Unpaused(address) + + +// Storage + +/// @notice Paused Storage Slot +#define constant PAUSED_SLOT = FREE_STORAGE_POINTER() + +/// @notice Unpaused representation +#define constant NOT_PAUSED = 0x01 + +/// @notice Paused representation +#define constant PAUSED = 0x02 + + +/// @notice Pausable constructor +#define macro PAUSABLE_CONSTRUCTOR() = takes (0) returns (0) { + [NOT_PAUSED] [PAUSED_SLOT] sstore // [] +} + +/// @notice whenNotPaused modifier +#define macro WHEN_NOT_PAUSED_MODIFIER() = takes (0) returns (0) { + [PAUSED_SLOT] sload // [isPaused] + [NOT_PAUSED] eq when_not_paused jumpi // [] + 0x00 dup1 revert // [] + when_not_paused: // [] +} + +/// @notice whenPaused modifier +#define macro WHEN_PAUSED_MODIFIER() = takes (0) returns (0) { + [PAUSED_SLOT] sload // [isPaused] + [PAUSED] eq when_paused jumpi // [] + 0x00 dup1 revert // [] + when_paused: // [] +} + +/// @notice return whether contract is paused +#define macro PAUSABLE_IS_PAUSED() = takes (0) returns (0) { + 0x01 // [1] + [PAUSED_SLOT] sload // [isPaused, 1] + sub // [bool] + 0x00 mstore // [] + 0x20 0x00 return // [] +} + +/// @notice Pause the contract +#define macro PAUSABLE_PAUSE() = takes (0) returns (0) { + WHEN_NOT_PAUSED_MODIFIER() // [] + + //emit Paused(address) + caller __EVENT_HASH(Paused) 0x00 dup1 // [0, 0, EVENT_PAUSED, msg.sender] + log2 // [] + + [PAUSED] [PAUSED_SLOT] sstore // [] + stop +} + +/// @notice Unpause the contract +#define macro PAUSABLE_UNPAUSE() = takes (0) returns (0) { + WHEN_PAUSED_MODIFIER() // [] + + //emit Unpaused(address) + caller __EVENT_HASH(Unpaused) 0x00 dup1 // [0, 0, EVENT_UNPAUSED, msg.sender] + log2 // [] + + [NOT_PAUSED] [PAUSED_SLOT] sstore // [] + stop +} diff --git a/src/utils/__TEMP__xmsfvcgannmmwswbxlbvrttkmvnfxjsyErrors.huff b/src/utils/__TEMP__xmsfvcgannmmwswbxlbvrttkmvnfxjsyErrors.huff new file mode 100644 index 00000000..e04e8e5b --- /dev/null +++ b/src/utils/__TEMP__xmsfvcgannmmwswbxlbvrttkmvnfxjsyErrors.huff @@ -0,0 +1,303 @@ +#define function simulateRequire() pure returns () +#define function simulateAssert() pure returns () +#define function simulateAssertEq() pure returns () +#define function simulateAssertNotEq() pure returns () +#define function simulateAssertMemEq() pure returns () +#define function simulateAssertMemNotEq() pure returns () +#define function simulateAssertStorageEq() nonpayable returns () +#define function simulateAssertStorageNotEq() nonpayable returns () +#define function simulateCompilerPanic() pure returns () +#define function simulateArithmeticOverflow() pure returns () +#define function simulateDivideByZero() pure returns () +#define function simulateInvalidEnumValue() pure returns () +#define function simulateInvalidStorageByteArray() pure returns () +#define function simulateEmptyArrayPop() pure returns () +#define function simulateArrayOutOfBounds() pure returns () +#define function simulateMemoryTooLarge() pure returns () +#define function simulateUninitializedFunctionPointer() pure returns () +#define function simulateBubbleUpIfFailed(address) view returns () + +#define constant REQUIRE_LENGTH = 0x06 +#define constant REQUIRE_STRING = 0x7265766572740000000000000000000000000000000000000000000000000000 + +#define macro MAIN() = takes (0) returns (0) { + pc calldataload 0xe0 shr + dup1 __FUNC_SIG(simulateRequire) eq simulate_require jumpi + dup1 __FUNC_SIG(simulateAssert) eq simulate_assert jumpi + dup1 __FUNC_SIG(simulateAssertEq) eq simulate_assert_eq jumpi + dup1 __FUNC_SIG(simulateAssertNotEq) eq simulate_assert_not_eq jumpi + dup1 __FUNC_SIG(simulateAssertMemEq) eq simulate_assert_mem_eq jumpi + dup1 __FUNC_SIG(simulateAssertMemNotEq) eq simulate_assert_mem_not_eq jumpi + dup1 __FUNC_SIG(simulateAssertStorageEq) eq simulate_assert_storage_eq jumpi + dup1 __FUNC_SIG(simulateAssertStorageNotEq) eq simulate_assert_storage_not_eq jumpi + dup1 __FUNC_SIG(simulateCompilerPanic) eq simulate_compiler_panic jumpi + dup1 __FUNC_SIG(simulateArithmeticOverflow) eq simulateArithmeticOverflow jumpi + dup1 __FUNC_SIG(simulateDivideByZero) eq simulateDivideByZero jumpi + dup1 __FUNC_SIG(simulateInvalidEnumValue) eq simulateInvalidEnumValue jumpi + dup1 __FUNC_SIG(simulateInvalidStorageByteArray) eq simulateInvalidStorageByteArray jumpi + dup1 __FUNC_SIG(simulateEmptyArrayPop) eq simulateEmptyArrayPop jumpi + dup1 __FUNC_SIG(simulateArrayOutOfBounds) eq simulateArrayOutOfBounds jumpi + dup1 __FUNC_SIG(simulateMemoryTooLarge) eq simulateMemoryTooLarge jumpi + dup1 __FUNC_SIG(simulateUninitializedFunctionPointer) eq simulateUninitializedFunctionPointer jumpi + dup1 __FUNC_SIG(simulateBubbleUpIfFailed) eq simulateBubbleUpIfFailed jumpi + + 0x00 0x00 revert + + simulate_require: + [REQUIRE_STRING] // [message] + [REQUIRE_LENGTH] // [message_length, message] + 0x00 // [false, message_length, message] + REQUIRE() // [] + + simulate_assert: + 0x00 // [false] + ASSERT() // [] + + simulate_assert_eq: + 0x01 0x00 // [0x00, 0x01] + ASSERT_EQ() + + simulate_assert_not_eq: + 0x00 0x00 // [0x00, 0x00] + ASSERT_NOT_EQ() + + simulate_assert_mem_eq: + 0x00 dup1 mstore + 0x01 0x20 mstore + ASSERT_MEM_EQ(0x00, 0x20) + + simulate_assert_mem_not_eq: + 0x00 dup1 mstore + 0x00 0x20 mstore + ASSERT_MEM_NOT_EQ(0x00, 0x20) + + simulate_assert_storage_eq: + 0x00 dup1 sstore + 0x01 dup1 sstore + ASSERT_STORAGE_EQ(0x00, 0x01) + + simulate_assert_storage_not_eq: + 0x00 dup1 sstore + 0x00 0x01 sstore + ASSERT_STORAGE_NOT_EQ(0x00, 0x01) + + simulate_compiler_panic: + [COMPILER_PANIC] + do_panic + jump + + simulateArithmeticOverflow: + [ARITHMETIC_OVERFLOW] + do_panic + jump + + simulateDivideByZero: + [DIVIDE_BY_ZERO] + do_panic + jump + + simulateInvalidEnumValue: + [INVALID_ENUM_VALUE] + do_panic + jump + + simulateInvalidStorageByteArray: + [INVALID_STORAGE_BYTE_ARRAY] + do_panic + jump + + simulateEmptyArrayPop: + [EMPTY_ARRAY_POP] + do_panic + jump + + simulateArrayOutOfBounds: + [ARRAY_OUT_OF_BOUNDS] + do_panic + jump + + simulateMemoryTooLarge: + [MEMORY_TOO_LARGE] + do_panic + jump + + simulateUninitializedFunctionPointer: + [UNINITIALIZED_FUNCTION_POINTER] + do_panic + jump + + simulateBubbleUpIfFailed: + 0x00 // [ret_size] + dup1 // [ret_offset, ret_size] + dup1 // [args_size, ret_offset, ret_size] + dup1 // [args_offset, args_size, ret_offst, ret_size] + dup1 // [value, args_offset, args_size, ret_offst, ret_size] + 0x04 // [addr_offset, value, args_offset, args_size, ret_offst, ret_size] + calldataload // [addr, value, args_offset, args_size, ret_offst, ret_size] + gas // [gas, addr, value, args_offset, args_size, ret_offst, ret_size] + call // [success] + BUBBLE_UP_IF_FAILED() // [] + + do_panic: + PANIC() +} + + +/// @title Errors +/// @notice SPDX-License-Identifier: MIT +/// @author jtriley.eth +/// @author clabby +/// @notice Custom error utilities. + +// https://docs.soliditylang.org/en/latest/control-structures.html?highlight=panic#panic-via-assert-and-error-via-require + +// Errors +#define error Error(string) +#define error Panic(uint256) + +// Constants +// Solidity Panic Codes +#define constant COMPILER_PANIC = 0x00 +#define constant ASSERT_FALSE = 0x01 +#define constant ARITHMETIC_OVERFLOW = 0x11 +#define constant DIVIDE_BY_ZERO = 0x12 +#define constant INVALID_ENUM_VALUE = 0x21 +#define constant INVALID_STORAGE_BYTE_ARRAY = 0x22 +#define constant EMPTY_ARRAY_POP = 0x31 +#define constant ARRAY_OUT_OF_BOUNDS = 0x32 +#define constant MEMORY_TOO_LARGE = 0x41 +#define constant UNINITIALIZED_FUNCTION_POINTER = 0x51 + +/* + +Solidity Require. Error `string` MUST be no greater than 32 bytes. + +MEMORY LAYOUT WHEN THROWN +| sig || message offset || message length || message "revert" | +0x08c379a 0000000000000000000000000000000000000000000000000000000000000020 0000000000000000000000000000000000000000000000000000000000000006 7265766572740000000000000000000000000000000000000000000000000000 + +*/ +#define macro REQUIRE() = takes (3) returns (0) { + // takes: // [condition, message_length, message] + do_not_throw // [do_not_throw_jumpdest, condition, message_length, message] + jumpi // [message_length, message] + __ERROR(Error) // [error_sig, , message_length, message] + 0x00 // [mem_ptr, error_sig, message_length, message] + mstore // [message_length, message] + 0x20 // [message_offset, message_length, message] + 0x04 // [message_offset_ptr, message_offset, message_length, message] + mstore // [message_length, message] + 0x24 // [message_length_ptr, message_length, message] + mstore // [message] + 0x44 // [message_ptr, message] + mstore // [] + 0x80 // [size] + 0x00 // [offset, size] + revert // [] + do_not_throw: // [message_length, message] + pop // [message] + pop // [] +} + +/* + +Solidity Panic. + +MEMORY LAYOUT WHEN THROWN +| sig || panic code | +0x4e487b71 0000000000000000000000000000000000000000000000000000000000000001 + +*/ +#define macro PANIC() = takes (1) returns (0) { + // takes: // [panic_code] + __ERROR(Panic) // [panic_sig, panic_code] + 0x00 // [panic_sig_offset, panic_sig, panic_code] + mstore // [panic_code] + 0x04 // [panic_code_offset, panic_code] + mstore // [] + 0x24 // [revert_size] + 0x00 // [revert_offset, revert_size] + revert // [] +} + +/* +Solidity Assert. + +MEMORY LAYOUT WHEN THROWN +| sig || assert failed panic code | +0x4e487b71 0000000000000000000000000000000000000000000000000000000000000001 + +*/ +#define macro ASSERT() = takes (1) returns (0) { + // takes: // [condition] + do_not_panic // [do_not_panic_jumpdest, condition] + jumpi // [] + [ASSERT_FALSE] // [assert_false] + PANIC() // [] + do_not_panic: // [] +} + +// Assert that two stack elements are equal +#define macro ASSERT_EQ() = { + // takes: [a, b] + eq // [a == b] + ASSERT() // [] +} + +// Assert that two stack elements are not equal +#define macro ASSERT_NOT_EQ() = { + // takes: [a, b] + eq iszero // [a != b] + ASSERT() // [] +} + +// Assert that two memory offsets contain equal words +#define macro ASSERT_MEM_EQ(ptr_a, ptr_b) = { + // takes: [] + mload // [b] + mload // [a, b] + eq // [a == b] + ASSERT() // [] +} + +// Assert that two memory offsets do not contain equal words +#define macro ASSERT_MEM_NOT_EQ(ptr_a, ptr_b) = { + // takes: [] + mload // [b] + mload // [a, b] + eq iszero // [a != b] + ASSERT() // [] +} + +// Assert that two storage slots contain equal words +#define macro ASSERT_STORAGE_EQ(slot_a, slot_b) = { + // takes: [] + sload // [b] + sload // [a, b] + eq // [a == b] + ASSERT() // [] +} + +// Assert that two storage slots do not contain equal words +#define macro ASSERT_STORAGE_NOT_EQ(slot_a, slot_b) = { + // takes: [] + sload // [b] + sload // [a, b] + eq iszero // [a != b] + ASSERT() // [] +} + +/* Bubbles up revert data if call failed. Call directly after `call`, `staticcall`, `delegatecall`. */ +#define macro BUBBLE_UP_IF_FAILED() = takes (1) returns (0) { + // takes: // [call_succeeded] + call_succeeded // [call_succeeded_jumpdest, call_succeeded] + jumpi // [] + returndatasize // [returndatasize] + 0x00 // [memory_offset, returndatasize] + returndatasize // [returndatasize, memory_offset, returndatasize] + dup2 // [returndata_offset, returndatasize, memory_offset, returndatasize] + dup3 // [memory_offset, returndata_offset, returndatasize, memory_offset, returndatasize] + returndatacopy // [memory_offset, returndatasize] + revert // [] + call_succeeded: +} diff --git a/src/utils/__TEMP__zzxsgvxvutylwrboumnhnihgplkcsjdrInsertionSort.huff b/src/utils/__TEMP__zzxsgvxvutylwrboumnhnihgplkcsjdrInsertionSort.huff new file mode 100644 index 00000000..2959ef82 --- /dev/null +++ b/src/utils/__TEMP__zzxsgvxvutylwrboumnhnihgplkcsjdrInsertionSort.huff @@ -0,0 +1,100 @@ +/// SPDX-License-Identifier: MIT + +/// @notice Insertion Sort Function +#define function insertionSort(uint256[]) nonpayable returns (uint256[]) + +/// @notice Performs insertion sort on raw calldata +#define macro INSERTION_SORT() = takes (0) returns (0) { + SORT() // [offset, arrSize] + return // [] +} + +/// @notice The contract entrypoint +#define macro MAIN() = takes(0) returns (0) { + returndatasize calldataload 0xe0 shr // [selector] + + // notice: we don't need to duplicate the selector here + // since the selector is consumed and only used once + __FUNC_SIG(insertionSort) eq jumpSort jumpi // [] + + // Reverts if selector not present. + returndatasize returndatasize revert + + jumpSort: + INSERTION_SORT() +} + + +/// @title Sort +/// @notice SPDX-License-Identifier: MIT +/// @author tanim0la +/// @notice Insertion sort implementation + +/* MACRO */ +/// @notice Returns two items `offSet` and `arrSize` +#define macro SORT() = takes (0) returns (2) { + + 0x04 calldatasize sub // [arrSize] + dup1 // [arrSize, arrSize] + 0x04 // [offset, arrSize, arrSize] + 0x40 // [mem, offset, arrSize, arrSize] + calldatacopy // [arrSize] + + 0x01 returndatasize mstore // i = 1 + 0x60 mload // [len, arrSize] + + // For loop + start: + // End if i == len + returndatasize mload // [i, len, arrSize] + dup2 dup2 // [i, len, i, len, arrSize] + eq end jumpi + + // Assign i to j + 0x20 mstore // [len, arrSize] + + // While loop + while: + returndatasize // [0, len, arrSize] + 0x20 mload dup2 dup2 // [j, 0, j, 0, len, arrSize] + gt // [cndt1, j, 0, len, arrSize] + + + // 0x80 + (0x20 * j) + dup2 0x20 mul 0x80 add // [mem[arr[j]], cndt1, j, 0, len, arrSize] + + // 0x80 + (0x20 * (j - 0x01)) + 0x01 dup4 sub 0x20 mul 0x80 add // [mem[arr[j - i]], mem[arr[j]], cndt1, j, 0, len, arrSize] + dup2 // [mem[arr[j]], mem[arr[j - 1]], mem[arr[j]], cndt1, j, 0, len, arrSize] + + mload // [arr[j], mem[arr[j - 1]], mem[arr[j]], cndt1, j, 0, len, arrSize] + dup2 mload // [arr[j - 1], arr[j], mem[arr[j - 1]], mem[arr[j]], cndt1, j, 0, len, arrSize] + + gt dup4 // [cndt1, cndt2, mem[arr[j - 1]], mem[arr[j]], cndt1, j, 0, len, arrSize] + and continueWhile jumpi // [mem[arr[j - 1]], mem[arr[j]], cndt1, j, 0, len, arrSize] + + // Go to continue + pop pop pop pop pop // [len, arrSize] + + // Increment i++ + returndatasize mload 0x01 add // [i + 1, len, arrSize] + returndatasize mstore start jump // [len, arrSize] + + // While block + continueWhile: + // arr[j - 1] = arr[j] + dup1 mload dup3 mload // [arr[j], arr[j - i], mem[arr[j - 1]], mem[arr[j]], cndt1, j, 0, len, arrSize] + dup3 mstore // [arr[j - 1], mem[arr[j - 1]], mem[arr[j]], cndt1, j, 0, len, arrSize] + + // arr[j] = arr[j - 1] + dup3 mstore // [mem[arr[j - 1], mem[arr[j]], cndt1, j, 0, len, arrSize] + + pop pop pop // [j, 0, len, arrSize] + + // Decrement j-- + 0x01 dup2 sub // [j - 1 ,j, 0, len, arrSize] + 0x20 mstore pop pop // [len, arrSize] + while jump + end: + pop pop 0x40 // [offset, arrSize] +} From 710d0f2dfc1db92f1d27b1b634a19843770dcacf Mon Sep 17 00:00:00 2001 From: Maddiaa0 <47148561+Maddiaa0@users.noreply.github.com> Date: Sat, 8 Jul 2023 20:32:42 +0000 Subject: [PATCH 2/3] feat: update huffmate to target shanghai --- foundry.toml | 1 + src/tokens/ERC20.huff | 2 +- src/tokens/interfaces/IERC20.sol | 2 +- src/utils/JumpTableUtil.huff | 1 - test/auth/Auth.t.sol | 2 +- test/auth/NonPayable.t.sol | 2 +- test/auth/OnlyContract.t.sol | 2 +- test/auth/Owned.t.sol | 2 +- test/auth/RolesAuthority.t.sol | 2 +- test/data-structures/Arrays.t.sol | 2 +- test/data-structures/Bytes.t.sol | 2 +- test/data-structures/Hashmap.t.sol | 2 +- test/factories/Factory.t.sol | 2 +- test/factories/ProxyFactory.t.sol | 2 +- test/math/FixedPointMath.t.sol | 2 +- test/math/Math.t.sol | 2 +- test/math/SafeMath.t.sol | 2 +- test/math/Trigonometry.t.sol | 2 +- test/mechanisms/huff-clones/HuffClone.t.sol | 2 +- test/mechanisms/huff-clones/HuffCloneFactory.t.sol | 2 +- test/mechanisms/huff-clones/Interfaces.sol | 2 +- test/mechanisms/huff-vrgda/LinearVRGDA.t.sol | 2 +- test/mechanisms/huff-vrgda/LogisticVRGDA.t.sol | 2 +- test/mechanisms/huff-vrgda/utils/SignedWadMath.sol | 2 +- test/proxies/Clones.t.sol | 2 +- test/proxies/ERC1967Proxy.t.sol | 2 +- test/proxies/mocks/MockBeacon.sol | 2 +- test/proxies/mocks/MockProxiableUUID.sol | 2 +- test/proxies/mocks/MockReturner.sol | 2 +- test/proxies/mocks/NotUUPSMockProxiableUUID.sol | 2 +- test/test-utils/FuzzingUtils.sol | 2 +- test/test-utils/NonMatchingSelectorHelper.sol | 2 +- test/tokens/ERC1155.t.sol | 2 +- test/tokens/ERC20.t.sol | 3 ++- test/tokens/ERC4626.t.sol | 2 +- test/tokens/ERC721.t.sol | 2 +- test/utils/BitPackLib.t.sol | 2 +- test/utils/CREATE3.t.sol | 2 +- test/utils/Calls.t.sol | 2 +- test/utils/Constants.t.sol | 2 +- test/utils/DateTimeLib.t.sol | 2 +- test/utils/ECDSA.t.sol | 2 +- test/utils/Errors.t.sol | 2 +- test/utils/Ethers.t.sol | 2 +- test/utils/InsertionSort.t.sol | 2 +- test/utils/JumpTableUtil.t.sol | 6 +++--- test/utils/LibBit.t.sol | 2 +- test/utils/MerkleDistributor.t.sol | 2 +- test/utils/MerkleProofLib.t.sol | 2 +- test/utils/Multicallable.t.sol | 2 +- test/utils/Pausable.t.sol | 2 +- test/utils/ReentrancyGuard.t.sol | 2 +- test/utils/Refunded.t.sol | 2 +- test/utils/SSTORE2.t.sol | 2 +- test/utils/SafeTransferLib.t.sol | 2 +- test/utils/Shuffling.t.sol | 2 +- test/utils/TSOwnable.t.sol | 2 +- test/utils/safe-transfer-lib-mocks/mocks/MockERC20.sol | 2 +- .../weird-tokens/MissingReturnToken.sol | 2 +- .../weird-tokens/ReturnsFalseToken.sol | 2 +- .../weird-tokens/ReturnsGarbageToken.sol | 2 +- .../weird-tokens/ReturnsTooLittleToken.sol | 2 +- .../weird-tokens/ReturnsTooMuchToken.sol | 2 +- .../weird-tokens/ReturnsTwoToken.sol | 2 +- .../safe-transfer-lib-mocks/weird-tokens/RevertingToken.sol | 2 +- 65 files changed, 67 insertions(+), 66 deletions(-) diff --git a/foundry.toml b/foundry.toml index d672a2c2..cd23a607 100644 --- a/foundry.toml +++ b/foundry.toml @@ -2,6 +2,7 @@ out = 'out' libs = ['lib'] ffi = true +evm_version = "shanghai" fs_permissions = [ { access = "read", path = "./test/auth/mocks/AuthWrappers.huff" }, { access = "read", path = "./test/auth/mocks/OwnedWrappers.huff" }, diff --git a/src/tokens/ERC20.huff b/src/tokens/ERC20.huff index 2a9bdfdf..0836ea8f 100644 --- a/src/tokens/ERC20.huff +++ b/src/tokens/ERC20.huff @@ -70,7 +70,7 @@ [INITIAL_DOMAIN_SEPARATOR] sstore // [] // Copy the runtime bytecode with constructor argument concatenated. - 0x67 // [offset] - constructor code size + 0x66 // [offset] - constructor code size dup1 // [offset, offset] codesize // [total_size, offset, offset] sub // [runtime_size, offset] diff --git a/src/tokens/interfaces/IERC20.sol b/src/tokens/interfaces/IERC20.sol index 8e4a26c6..08e2ac86 100644 --- a/src/tokens/interfaces/IERC20.sol +++ b/src/tokens/interfaces/IERC20.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.15; +pragma solidity ^0.8.19; interface TSOwnable { function owner() external returns (address); diff --git a/src/utils/JumpTableUtil.huff b/src/utils/JumpTableUtil.huff index 1fb6e924..76d42633 100644 --- a/src/utils/JumpTableUtil.huff +++ b/src/utils/JumpTableUtil.huff @@ -1,4 +1,3 @@ - /// @title JumpTableUtil /// @notice SPDX-License-Identifier: MIT /// @author clabby diff --git a/test/auth/Auth.t.sol b/test/auth/Auth.t.sol index 9798ff64..0423a87d 100644 --- a/test/auth/Auth.t.sol +++ b/test/auth/Auth.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.15; +pragma solidity ^0.8.19; import "forge-std/Test.sol"; import "forge-std/console.sol"; diff --git a/test/auth/NonPayable.t.sol b/test/auth/NonPayable.t.sol index 442ca17f..687d3b68 100644 --- a/test/auth/NonPayable.t.sol +++ b/test/auth/NonPayable.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.15; +pragma solidity ^0.8.19; import "forge-std/Test.sol"; import {HuffDeployer} from "foundry-huff/HuffDeployer.sol"; diff --git a/test/auth/OnlyContract.t.sol b/test/auth/OnlyContract.t.sol index 6bfafd93..e290afd1 100644 --- a/test/auth/OnlyContract.t.sol +++ b/test/auth/OnlyContract.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.15; +pragma solidity ^0.8.19; import {Test} from "forge-std/Test.sol"; diff --git a/test/auth/Owned.t.sol b/test/auth/Owned.t.sol index 421ab4ab..b8d9995c 100644 --- a/test/auth/Owned.t.sol +++ b/test/auth/Owned.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.15; +pragma solidity ^0.8.19; import "forge-std/Test.sol"; import {HuffConfig} from "foundry-huff/HuffConfig.sol"; diff --git a/test/auth/RolesAuthority.t.sol b/test/auth/RolesAuthority.t.sol index 3dbf60a8..ba65f450 100644 --- a/test/auth/RolesAuthority.t.sol +++ b/test/auth/RolesAuthority.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.15; +pragma solidity ^0.8.19; import "forge-std/Test.sol"; import { HuffDeployer } from "foundry-huff/HuffDeployer.sol"; diff --git a/test/data-structures/Arrays.t.sol b/test/data-structures/Arrays.t.sol index a7206e24..215c07d0 100644 --- a/test/data-structures/Arrays.t.sol +++ b/test/data-structures/Arrays.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.15; +pragma solidity ^0.8.19; import "foundry-huff/HuffDeployer.sol"; import "forge-std/Test.sol"; diff --git a/test/data-structures/Bytes.t.sol b/test/data-structures/Bytes.t.sol index 27584c08..931a3ed6 100644 --- a/test/data-structures/Bytes.t.sol +++ b/test/data-structures/Bytes.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.15; +pragma solidity ^0.8.19; import "foundry-huff/HuffDeployer.sol"; import "forge-std/Test.sol"; diff --git a/test/data-structures/Hashmap.t.sol b/test/data-structures/Hashmap.t.sol index e0b53377..ca61bf18 100644 --- a/test/data-structures/Hashmap.t.sol +++ b/test/data-structures/Hashmap.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.15; +pragma solidity ^0.8.19; import "forge-std/Test.sol"; import {HuffConfig} from "foundry-huff/HuffConfig.sol"; diff --git a/test/factories/Factory.t.sol b/test/factories/Factory.t.sol index 6341d520..c16ff162 100644 --- a/test/factories/Factory.t.sol +++ b/test/factories/Factory.t.sol @@ -1,2 +1,2 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.15; +pragma solidity ^0.8.19; diff --git a/test/factories/ProxyFactory.t.sol b/test/factories/ProxyFactory.t.sol index 6341d520..c16ff162 100644 --- a/test/factories/ProxyFactory.t.sol +++ b/test/factories/ProxyFactory.t.sol @@ -1,2 +1,2 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.15; +pragma solidity ^0.8.19; diff --git a/test/math/FixedPointMath.t.sol b/test/math/FixedPointMath.t.sol index f1d038c1..dd623230 100644 --- a/test/math/FixedPointMath.t.sol +++ b/test/math/FixedPointMath.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.15; +pragma solidity ^0.8.19; import "foundry-huff/HuffDeployer.sol"; import "forge-std/Test.sol"; diff --git a/test/math/Math.t.sol b/test/math/Math.t.sol index f4634799..a5167b23 100644 --- a/test/math/Math.t.sol +++ b/test/math/Math.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.15; +pragma solidity ^0.8.19; import "forge-std/Test.sol"; import "foundry-huff/HuffDeployer.sol"; diff --git a/test/math/SafeMath.t.sol b/test/math/SafeMath.t.sol index 731c59ba..b2b4a14c 100644 --- a/test/math/SafeMath.t.sol +++ b/test/math/SafeMath.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.15; +pragma solidity ^0.8.19; import "forge-std/Test.sol"; import "foundry-huff/HuffDeployer.sol"; diff --git a/test/math/Trigonometry.t.sol b/test/math/Trigonometry.t.sol index a67f22b8..7b3ba2d2 100644 --- a/test/math/Trigonometry.t.sol +++ b/test/math/Trigonometry.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.15; +pragma solidity ^0.8.19; import "foundry-huff/HuffDeployer.sol"; import "forge-std/Test.sol"; diff --git a/test/mechanisms/huff-clones/HuffClone.t.sol b/test/mechanisms/huff-clones/HuffClone.t.sol index f726dbec..73c178ea 100644 --- a/test/mechanisms/huff-clones/HuffClone.t.sol +++ b/test/mechanisms/huff-clones/HuffClone.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: BSD -pragma solidity ^0.8.15; +pragma solidity ^0.8.19; import {Test} from "forge-std/Test.sol"; import {HuffDeployer} from "foundry-huff/HuffDeployer.sol"; diff --git a/test/mechanisms/huff-clones/HuffCloneFactory.t.sol b/test/mechanisms/huff-clones/HuffCloneFactory.t.sol index af1581cb..5600c423 100644 --- a/test/mechanisms/huff-clones/HuffCloneFactory.t.sol +++ b/test/mechanisms/huff-clones/HuffCloneFactory.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: BSD -pragma solidity ^0.8.15; +pragma solidity ^0.8.19; import {Test} from "forge-std/Test.sol"; import {HuffDeployer} from "foundry-huff/HuffDeployer.sol"; diff --git a/test/mechanisms/huff-clones/Interfaces.sol b/test/mechanisms/huff-clones/Interfaces.sol index 646ee1ee..9da75578 100644 --- a/test/mechanisms/huff-clones/Interfaces.sol +++ b/test/mechanisms/huff-clones/Interfaces.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: BSD -pragma solidity ^0.8.15; +pragma solidity ^0.8.19; interface IExampleClone { function param1() external pure returns (address); diff --git a/test/mechanisms/huff-vrgda/LinearVRGDA.t.sol b/test/mechanisms/huff-vrgda/LinearVRGDA.t.sol index eca307f9..f15424d2 100644 --- a/test/mechanisms/huff-vrgda/LinearVRGDA.t.sol +++ b/test/mechanisms/huff-vrgda/LinearVRGDA.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.15; +pragma solidity ^0.8.19; import "forge-std/Test.sol"; diff --git a/test/mechanisms/huff-vrgda/LogisticVRGDA.t.sol b/test/mechanisms/huff-vrgda/LogisticVRGDA.t.sol index 5918e037..93426acd 100644 --- a/test/mechanisms/huff-vrgda/LogisticVRGDA.t.sol +++ b/test/mechanisms/huff-vrgda/LogisticVRGDA.t.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.15; +pragma solidity ^0.8.19; import {DSTestPlus} from "solmate/test/utils/DSTestPlus.sol"; diff --git a/test/mechanisms/huff-vrgda/utils/SignedWadMath.sol b/test/mechanisms/huff-vrgda/utils/SignedWadMath.sol index 99e46512..b256a3dd 100644 --- a/test/mechanisms/huff-vrgda/utils/SignedWadMath.sol +++ b/test/mechanisms/huff-vrgda/utils/SignedWadMath.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.15; +pragma solidity ^0.8.19; /// @title Signed Wad Math /// @author transmissions11 diff --git a/test/proxies/Clones.t.sol b/test/proxies/Clones.t.sol index a40153df..ae35ab1f 100644 --- a/test/proxies/Clones.t.sol +++ b/test/proxies/Clones.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.15; +pragma solidity 0.8.19; import "foundry-huff/HuffDeployer.sol"; diff --git a/test/proxies/ERC1967Proxy.t.sol b/test/proxies/ERC1967Proxy.t.sol index c0bdf468..114f8dd6 100644 --- a/test/proxies/ERC1967Proxy.t.sol +++ b/test/proxies/ERC1967Proxy.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.15; +pragma solidity 0.8.19; import "foundry-huff/HuffDeployer.sol"; import "forge-std/Test.sol"; diff --git a/test/proxies/mocks/MockBeacon.sol b/test/proxies/mocks/MockBeacon.sol index 97969c1a..5af41004 100644 --- a/test/proxies/mocks/MockBeacon.sol +++ b/test/proxies/mocks/MockBeacon.sol @@ -1,5 +1,5 @@ -pragma solidity 0.8.15; +pragma solidity 0.8.19; /** * @dev This is the interface that {BeaconProxy} expects of its beacon. diff --git a/test/proxies/mocks/MockProxiableUUID.sol b/test/proxies/mocks/MockProxiableUUID.sol index e73fdee6..e74fbfd8 100644 --- a/test/proxies/mocks/MockProxiableUUID.sol +++ b/test/proxies/mocks/MockProxiableUUID.sol @@ -1,4 +1,4 @@ -pragma solidity 0.8.15; +pragma solidity 0.8.19; import { MockERC1155 } from "solmate/test/utils/mocks/MockERC1155.sol"; diff --git a/test/proxies/mocks/MockReturner.sol b/test/proxies/mocks/MockReturner.sol index 8a354a17..3e393820 100644 --- a/test/proxies/mocks/MockReturner.sol +++ b/test/proxies/mocks/MockReturner.sol @@ -1,4 +1,4 @@ -pragma solidity 0.8.15; +pragma solidity 0.8.19; /// @dev Used to test proxies that they can both receive and return data contract MockReturner { diff --git a/test/proxies/mocks/NotUUPSMockProxiableUUID.sol b/test/proxies/mocks/NotUUPSMockProxiableUUID.sol index a227d5f3..9465246a 100644 --- a/test/proxies/mocks/NotUUPSMockProxiableUUID.sol +++ b/test/proxies/mocks/NotUUPSMockProxiableUUID.sol @@ -1,4 +1,4 @@ -pragma solidity 0.8.15; +pragma solidity 0.8.19; import { MockERC1155 } from "solmate/test/utils/mocks/MockERC1155.sol"; diff --git a/test/test-utils/FuzzingUtils.sol b/test/test-utils/FuzzingUtils.sol index 1a2fb488..3f65ec2b 100644 --- a/test/test-utils/FuzzingUtils.sol +++ b/test/test-utils/FuzzingUtils.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.15; +pragma solidity ^0.8.19; // adapter from: https://github.com/transmissions11/solmate/blob/main/src/test/utils/DSTestPlus.sol abstract contract FuzzingUtils { diff --git a/test/test-utils/NonMatchingSelectorHelper.sol b/test/test-utils/NonMatchingSelectorHelper.sol index ec00f67a..2875f14b 100644 --- a/test/test-utils/NonMatchingSelectorHelper.sol +++ b/test/test-utils/NonMatchingSelectorHelper.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.15; +pragma solidity ^0.8.19; import "forge-std/Test.sol"; diff --git a/test/tokens/ERC1155.t.sol b/test/tokens/ERC1155.t.sol index 664245dc..6f8d2176 100644 --- a/test/tokens/ERC1155.t.sol +++ b/test/tokens/ERC1155.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.15; +pragma solidity ^0.8.19; import "foundry-huff/HuffDeployer.sol"; import "forge-std/Test.sol"; diff --git a/test/tokens/ERC20.t.sol b/test/tokens/ERC20.t.sol index a44402fc..7e40ec6a 100644 --- a/test/tokens/ERC20.t.sol +++ b/test/tokens/ERC20.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.15; +pragma solidity ^0.8.19; import "foundry-huff/HuffDeployer.sol"; import "forge-std/Test.sol"; @@ -53,6 +53,7 @@ contract ERC20Test is Test { // Deploy the Mintable ERC20 address mintableTokenAddress = HuffDeployer.config() + .with_evm_version("shanghai") .with_code(mintable_wrapper) .with_deployer(deployer) .with_args(bytes.concat(abi.encode("Token"), abi.encode("TKN"), abi.encode(DECIMALS))) diff --git a/test/tokens/ERC4626.t.sol b/test/tokens/ERC4626.t.sol index 7a9fab1d..50edc05d 100644 --- a/test/tokens/ERC4626.t.sol +++ b/test/tokens/ERC4626.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.15; +pragma solidity ^0.8.19; import "forge-std/Test.sol"; import "foundry-huff/HuffDeployer.sol"; diff --git a/test/tokens/ERC721.t.sol b/test/tokens/ERC721.t.sol index d8686529..b7a1ad81 100644 --- a/test/tokens/ERC721.t.sol +++ b/test/tokens/ERC721.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.15; +pragma solidity ^0.8.19; import "forge-std/Test.sol"; import "foundry-huff/HuffDeployer.sol"; diff --git a/test/utils/BitPackLib.t.sol b/test/utils/BitPackLib.t.sol index 990dc8fa..7af81e44 100644 --- a/test/utils/BitPackLib.t.sol +++ b/test/utils/BitPackLib.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.15; +pragma solidity ^0.8.19; import "forge-std/Test.sol"; import "foundry-huff/HuffDeployer.sol"; diff --git a/test/utils/CREATE3.t.sol b/test/utils/CREATE3.t.sol index 962e58b1..f100e92d 100644 --- a/test/utils/CREATE3.t.sol +++ b/test/utils/CREATE3.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.15; +pragma solidity ^0.8.19; import "foundry-huff/HuffDeployer.sol"; import "forge-std/Test.sol"; diff --git a/test/utils/Calls.t.sol b/test/utils/Calls.t.sol index b97ba19f..dd9762ec 100644 --- a/test/utils/Calls.t.sol +++ b/test/utils/Calls.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.15; +pragma solidity ^0.8.19; import "forge-std/Test.sol"; import "foundry-huff/HuffDeployer.sol"; diff --git a/test/utils/Constants.t.sol b/test/utils/Constants.t.sol index aa5de68f..d1cc796d 100644 --- a/test/utils/Constants.t.sol +++ b/test/utils/Constants.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.15; +pragma solidity ^0.8.19; import "forge-std/Test.sol"; import "foundry-huff/HuffDeployer.sol"; diff --git a/test/utils/DateTimeLib.t.sol b/test/utils/DateTimeLib.t.sol index 254057d4..1a581a67 100644 --- a/test/utils/DateTimeLib.t.sol +++ b/test/utils/DateTimeLib.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: Unlicense -pragma solidity ^0.8.15; +pragma solidity ^0.8.19; import "foundry-huff/HuffDeployer.sol"; import "forge-std/console.sol"; diff --git a/test/utils/ECDSA.t.sol b/test/utils/ECDSA.t.sol index 7a9891d3..d14776c2 100644 --- a/test/utils/ECDSA.t.sol +++ b/test/utils/ECDSA.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.15; +pragma solidity ^0.8.19; import "forge-std/Test.sol"; import "foundry-huff/HuffDeployer.sol"; diff --git a/test/utils/Errors.t.sol b/test/utils/Errors.t.sol index a87311a8..fbaa66f0 100644 --- a/test/utils/Errors.t.sol +++ b/test/utils/Errors.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.15; +pragma solidity ^0.8.19; import "foundry-huff/HuffDeployer.sol"; import "forge-std/Test.sol"; diff --git a/test/utils/Ethers.t.sol b/test/utils/Ethers.t.sol index 8c7a7a6d..1ab7112d 100644 --- a/test/utils/Ethers.t.sol +++ b/test/utils/Ethers.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.15; +pragma solidity ^0.8.19; import "forge-std/Test.sol"; import "foundry-huff/HuffDeployer.sol"; diff --git a/test/utils/InsertionSort.t.sol b/test/utils/InsertionSort.t.sol index b10edde8..a1ac9782 100644 --- a/test/utils/InsertionSort.t.sol +++ b/test/utils/InsertionSort.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.15; +pragma solidity ^0.8.19; import "foundry-huff/HuffDeployer.sol"; import "forge-std/Test.sol"; diff --git a/test/utils/JumpTableUtil.t.sol b/test/utils/JumpTableUtil.t.sol index 2a2b7b2b..dae5fd7c 100644 --- a/test/utils/JumpTableUtil.t.sol +++ b/test/utils/JumpTableUtil.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.15; +pragma solidity ^0.8.19; import "foundry-huff/HuffDeployer.sol"; import "forge-std/Test.sol"; @@ -12,7 +12,7 @@ interface IJumpTableUtil { } contract JumpTableUtilTest is Test { - uint constant FIRST_LABEL_PC = 147; + uint constant FIRST_LABEL_PC = 141; IJumpTableUtil jtUtil; @@ -20,7 +20,7 @@ contract JumpTableUtilTest is Test { /// @notice deploy a new instance of IJumpTableUtil by /// passing in the address of the deployed Huff contract string memory wrapper_code = vm.readFile("test/utils/mocks/JumpTableUtilWrappers.huff"); - jtUtil = IJumpTableUtil(HuffDeployer.deploy_with_code("utils/JumpTableUtil", wrapper_code)); + jtUtil = IJumpTableUtil(HuffDeployer.config().with_evm_version("shanghai").with_code(wrapper_code).deploy("utils/JumpTableUtil")); } function testGetJumpdestFromJT_Mem() public { diff --git a/test/utils/LibBit.t.sol b/test/utils/LibBit.t.sol index cf6a235a..e84e2b73 100644 --- a/test/utils/LibBit.t.sol +++ b/test/utils/LibBit.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.15; +pragma solidity ^0.8.19; import "foundry-huff/HuffDeployer.sol"; import "forge-std/Test.sol"; diff --git a/test/utils/MerkleDistributor.t.sol b/test/utils/MerkleDistributor.t.sol index 374438ec..080b9e34 100644 --- a/test/utils/MerkleDistributor.t.sol +++ b/test/utils/MerkleDistributor.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.15; +pragma solidity ^0.8.19; import "foundry-huff/HuffDeployer.sol"; import "forge-std/Test.sol"; diff --git a/test/utils/MerkleProofLib.t.sol b/test/utils/MerkleProofLib.t.sol index e2bf1355..4aa72e42 100644 --- a/test/utils/MerkleProofLib.t.sol +++ b/test/utils/MerkleProofLib.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.15; +pragma solidity ^0.8.19; import "foundry-huff/HuffDeployer.sol"; import "forge-std/Test.sol"; diff --git a/test/utils/Multicallable.t.sol b/test/utils/Multicallable.t.sol index 10e2e869..cac819b6 100644 --- a/test/utils/Multicallable.t.sol +++ b/test/utils/Multicallable.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.15; +pragma solidity ^0.8.19; import "foundry-huff/HuffDeployer.sol"; import "forge-std/Test.sol"; diff --git a/test/utils/Pausable.t.sol b/test/utils/Pausable.t.sol index 66e80e9f..f2282819 100644 --- a/test/utils/Pausable.t.sol +++ b/test/utils/Pausable.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.15; +pragma solidity ^0.8.19; import "foundry-huff/HuffDeployer.sol"; import "forge-std/Test.sol"; diff --git a/test/utils/ReentrancyGuard.t.sol b/test/utils/ReentrancyGuard.t.sol index e5ca2641..85a0ff4b 100644 --- a/test/utils/ReentrancyGuard.t.sol +++ b/test/utils/ReentrancyGuard.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.15; +pragma solidity ^0.8.19; import "foundry-huff/HuffDeployer.sol"; import "forge-std/Test.sol"; diff --git a/test/utils/Refunded.t.sol b/test/utils/Refunded.t.sol index 76a4074a..48bded83 100644 --- a/test/utils/Refunded.t.sol +++ b/test/utils/Refunded.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.15; +pragma solidity ^0.8.19; import "foundry-huff/HuffDeployer.sol"; import "forge-std/Test.sol"; diff --git a/test/utils/SSTORE2.t.sol b/test/utils/SSTORE2.t.sol index cc593a71..b189246d 100644 --- a/test/utils/SSTORE2.t.sol +++ b/test/utils/SSTORE2.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.15; +pragma solidity ^0.8.19; import "foundry-huff/HuffDeployer.sol"; import "forge-std/Test.sol"; diff --git a/test/utils/SafeTransferLib.t.sol b/test/utils/SafeTransferLib.t.sol index b83c2a1f..07ce57f9 100644 --- a/test/utils/SafeTransferLib.t.sol +++ b/test/utils/SafeTransferLib.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.15; +pragma solidity 0.8.19; import {MockERC20} from "./safe-transfer-lib-mocks/mocks/MockERC20.sol"; import {RevertingToken} from "./safe-transfer-lib-mocks/weird-tokens/RevertingToken.sol"; diff --git a/test/utils/Shuffling.t.sol b/test/utils/Shuffling.t.sol index d9dea688..425ddbd8 100644 --- a/test/utils/Shuffling.t.sol +++ b/test/utils/Shuffling.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.15; +pragma solidity ^0.8.19; import { Test } from "forge-std/Test.sol"; import { console2 } from "forge-std/console2.sol"; diff --git a/test/utils/TSOwnable.t.sol b/test/utils/TSOwnable.t.sol index 7849e1c6..119cc34b 100644 --- a/test/utils/TSOwnable.t.sol +++ b/test/utils/TSOwnable.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.15; +pragma solidity ^0.8.19; import "foundry-huff/HuffConfig.sol"; import "forge-std/Test.sol"; diff --git a/test/utils/safe-transfer-lib-mocks/mocks/MockERC20.sol b/test/utils/safe-transfer-lib-mocks/mocks/MockERC20.sol index 3adb1f5c..846ba347 100644 --- a/test/utils/safe-transfer-lib-mocks/mocks/MockERC20.sol +++ b/test/utils/safe-transfer-lib-mocks/mocks/MockERC20.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.15; +pragma solidity ^0.8.19; import {ERC20} from "solmate/tokens/ERC20.sol"; diff --git a/test/utils/safe-transfer-lib-mocks/weird-tokens/MissingReturnToken.sol b/test/utils/safe-transfer-lib-mocks/weird-tokens/MissingReturnToken.sol index 5e94a0e0..6e276b7b 100644 --- a/test/utils/safe-transfer-lib-mocks/weird-tokens/MissingReturnToken.sol +++ b/test/utils/safe-transfer-lib-mocks/weird-tokens/MissingReturnToken.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.15; +pragma solidity ^0.8.19; contract MissingReturnToken { /*/////////////////////////////////////////////////////////////// diff --git a/test/utils/safe-transfer-lib-mocks/weird-tokens/ReturnsFalseToken.sol b/test/utils/safe-transfer-lib-mocks/weird-tokens/ReturnsFalseToken.sol index c0137e12..c29416bb 100644 --- a/test/utils/safe-transfer-lib-mocks/weird-tokens/ReturnsFalseToken.sol +++ b/test/utils/safe-transfer-lib-mocks/weird-tokens/ReturnsFalseToken.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.15; +pragma solidity ^0.8.19; contract ReturnsFalseToken { /*/////////////////////////////////////////////////////////////// diff --git a/test/utils/safe-transfer-lib-mocks/weird-tokens/ReturnsGarbageToken.sol b/test/utils/safe-transfer-lib-mocks/weird-tokens/ReturnsGarbageToken.sol index 3edcb167..b53ad856 100644 --- a/test/utils/safe-transfer-lib-mocks/weird-tokens/ReturnsGarbageToken.sol +++ b/test/utils/safe-transfer-lib-mocks/weird-tokens/ReturnsGarbageToken.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.15; +pragma solidity ^0.8.19; contract ReturnsGarbageToken { /*/////////////////////////////////////////////////////////////// diff --git a/test/utils/safe-transfer-lib-mocks/weird-tokens/ReturnsTooLittleToken.sol b/test/utils/safe-transfer-lib-mocks/weird-tokens/ReturnsTooLittleToken.sol index 03b997c7..8d8690b9 100644 --- a/test/utils/safe-transfer-lib-mocks/weird-tokens/ReturnsTooLittleToken.sol +++ b/test/utils/safe-transfer-lib-mocks/weird-tokens/ReturnsTooLittleToken.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.15; +pragma solidity ^0.8.19; contract ReturnsTooLittleToken { /*/////////////////////////////////////////////////////////////// diff --git a/test/utils/safe-transfer-lib-mocks/weird-tokens/ReturnsTooMuchToken.sol b/test/utils/safe-transfer-lib-mocks/weird-tokens/ReturnsTooMuchToken.sol index 69774c8a..5ef2da9e 100644 --- a/test/utils/safe-transfer-lib-mocks/weird-tokens/ReturnsTooMuchToken.sol +++ b/test/utils/safe-transfer-lib-mocks/weird-tokens/ReturnsTooMuchToken.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.15; +pragma solidity ^0.8.19; contract ReturnsTooMuchToken { /*/////////////////////////////////////////////////////////////// diff --git a/test/utils/safe-transfer-lib-mocks/weird-tokens/ReturnsTwoToken.sol b/test/utils/safe-transfer-lib-mocks/weird-tokens/ReturnsTwoToken.sol index b4b7e46a..3554325b 100644 --- a/test/utils/safe-transfer-lib-mocks/weird-tokens/ReturnsTwoToken.sol +++ b/test/utils/safe-transfer-lib-mocks/weird-tokens/ReturnsTwoToken.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.15; +pragma solidity ^0.8.19; contract ReturnsTwoToken { /*/////////////////////////////////////////////////////////////// diff --git a/test/utils/safe-transfer-lib-mocks/weird-tokens/RevertingToken.sol b/test/utils/safe-transfer-lib-mocks/weird-tokens/RevertingToken.sol index 99c051eb..a7c9af5c 100644 --- a/test/utils/safe-transfer-lib-mocks/weird-tokens/RevertingToken.sol +++ b/test/utils/safe-transfer-lib-mocks/weird-tokens/RevertingToken.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.15; +pragma solidity ^0.8.19; contract RevertingToken { /*/////////////////////////////////////////////////////////////// From 38c749943e84ad0d9e8b4ad350fd6007769aa537 Mon Sep 17 00:00:00 2001 From: Maddiaa0 <47148561+Maddiaa0@users.noreply.github.com> Date: Sat, 8 Jul 2023 20:36:57 +0000 Subject: [PATCH 3/3] chore(deps): target shanghai supported deployer for tests --- .gitmodules | 1 - lib/foundry-huff | 2 +- ...bcbtcjlsalfjomvpsarxoeqmfengiahvOwned.huff | 106 - ...jnrubnscbigchdduxlqllnuupOnlyContract.huff | 26 - ...gjqqvwuwnofsrtwqcnwpvegncntNonPayable.huff | 27 - ...mmmqoxevqxajvrhicbguifoRolesAuthority.huff | 314 --- ...fjpzjdeotdemryddmmyhqlqRolesAuthority.huff | 314 --- ...orycdmcbstquohvoehulrstRolesAuthority.huff | 314 --- ...rlgdtvsadoebscpgqfqrmgtsohzNonPayable.huff | 27 - ...vmqkfekoylppiiwxfdjnbfnRolesAuthority.huff | 314 --- ...qnjmdgxfwtecsggrrzgqbnqyqOnlyContract.huff | 26 - ...zvezglymjookpccrxwupfpflpekwphopOwned.huff | 106 - ...bkprxxmslvmupkpkwuxxniuwscdqqrnArrays.huff | 121 -- ...wgxfmgyfyneyghrepikbyjmyskqxskHashmap.huff | 317 --- ...xhhzaaidyagiaawzeyxpvkgxcxwtgqHashmap.huff | 317 --- ...lwkvhrrmofongwpxrjtworcwgnfqpxluBytes.huff | 349 ---- ...wmivzahxlhrjuiphjztstbcaymhckevArrays.huff | 121 -- ...wvnaxkgsgqemkcqoqqvognrxtldwtppxBytes.huff | 349 ---- ..._agffsybhummgrdmhvrzqoxrnkhupycfeMath.huff | 319 --- ...xtadnkjdmxsyyimfngsleoolwhcqtSafeMath.huff | 153 -- ...nyeazoevkblfjmhdomwtqwoFixedPointMath.huff | 1093 ---------- ...opkbndglbmvjbzlrpyrrzphnrTrigonometry.huff | 218 -- ...edbspprhymlfrgxlfepgepcrvTrigonometry.huff | 218 -- ...uxpdpeuvffbywnubcftdxsyFixedPointMath.huff | 1093 ---------- ..._qvmazraiuhrdvuoecpapxakdrzpwpmuqMath.huff | 319 --- ...imbuhetstepqivcpdmtxszazlqpnnSafeMath.huff | 153 -- ...dwsqmdvneonbcfprxtzfbmhkuExampleClone.huff | 77 - ...edeoorfkumjbbbagtfehbslnhExampleClone.huff | 77 - ...jajsmfrshnyoafedbhvmybxcfExampleClone.huff | 77 - ...qgllfjrqfvrmjmhzvpeefnmpcExampleClone.huff | 77 - ...dlyztnvsbkuhzfucpimehhtdLogisticVRGDA.huff | 77 - ...nwnrmtgswdmaharirrkhhznvgtLinearVRGDA.huff | 57 - ...lavwmvnufiarmtrrvilwbhnhmfuxofvClones.huff | 213 -- ...rlnsihsjssxbghxugniamuyipERC1967Proxy.huff | 158 -- ...lwhmiuazdwnqpgoxdvgcsfczvtfymagClones.huff | 213 -- ...blgmhozyfyviczblaggscrgixERC1967Proxy.huff | 158 -- ...fztznazwowexesrohcdykwsmvfkclmuyERC20.huff | 676 ------- ...olyemymwzenpqjpuukwgitehudafctpwERC20.huff | 676 ------- ...qsfkvbhimsywiqwbdlilqoxezxnqvipERC721.huff | 787 -------- ...pvmgiyjorautmnplhzvgjsaeubpvhbERC4626.huff | 859 -------- ...vaewlzfkyljuiwoxdrktdnlhsuzsmbhERC721.huff | 787 -------- ...gqnylgrbytfwvkvdnlnpcvxmcecsliERC4626.huff | 859 -------- src/tokens/interfaces/IERC20.sol | 2 +- ...kbbusaspkdjqohbmhkbfmghcmmpksnCREATE3.huff | 177 -- ...qwgufgegzhdrxxamgnvfwtnzJumpTableUtil.huff | 149 -- ...fqjrpihtljpxmlgbwuzstqlMerkleProofLib.huff | 86 - ...ubbndjqnadwlvmuebjtdnnpdjprqConstants.huff | 1789 ----------------- ...qdaprqvhayryuhporeghmzSafeTransferLib.huff | 202 -- ...ctwgjphmybkljahoybtnldrrcpneywglECDSA.huff | 305 --- ...wfcmbyyrjifcrrrqvnmskahrxtfwfPausable.huff | 131 -- ...dolvqpolutctxhctjzvajsrpbtpqfvdlCalls.huff | 217 -- ...medggubevwdmphskibtxMerkleDistributor.huff | 247 --- ...rijckuxiernloalienlasrtffackConstants.huff | 1789 ----------------- ...yomwxkixnogyzbecekrqolgmjnwpgibLibBit.huff | 267 --- ...sfweqvmnghgiyyjyzxhruyzqbslBitPackLib.huff | 104 - ...blaazsrdhqxfgjsonhnpjloMerkleProofLib.huff | 86 - ...wzbaphyfhugpyejapdmpmaanfaqcTSOwnable.huff | 172 -- ...byoimpybpmxmyrddbxuhherfeclBitPackLib.huff | 104 - ...tonvmuwvpsgnhyhrztoimrzkyqskTSOwnable.huff | 172 -- ...zlramplmuvmnsgrxrurevmmugyklixkEthers.huff | 47 - ...trgmsogdgtpmxmtwqmpdocReentrancyGuard.huff | 127 -- ...cylvhdduoakglqjyfagmmbgbJumpTableUtil.huff | 149 -- ...xgytjvcjspqzqpxtbelyxicffhqxfrSSTORE2.huff | 132 -- ...jwomkxvqpeatpkwmzsmvjaneohelmRefunded.huff | 97 - ...bfpunncyiouwtmltswyzljambbxxShuffling.huff | 68 - ...rpqdglcwrdylrneycegnebReentrancyGuard.huff | 127 -- ...wyyoypwjyhbfuzsxxekolsbwxgwxsdSSTORE2.huff | 132 -- ...pohrkhyvnxmaxjzqlkackypaopwtytiErrors.huff | 303 --- ...suvrwjmqtxbpjcrrcoacbfeiivquShuffling.huff | 68 - ...bvbklotqjimwddbdrttqayfxbbmavfvLibBit.huff | 267 --- ...qfzbthtrligkzrxhdcwizlbkonnnqqiyCalls.huff | 217 -- ...cokotvnwlrlotlmzautjwxvsMulticallable.huff | 233 --- ...ryraejdcasobgumhdtbwarjszpnlvasmECDSA.huff | 305 --- ...fwvdxpickfrbtnbbaudfvqefkatoiRefunded.huff | 97 - ...osskvfeygpuobkhcslnvMerkleDistributor.huff | 247 --- ...uhcelrjhrahufjtvdthjstmmMulticallable.huff | 233 --- ...wdnvquznelrjppmvqtmvduSafeTransferLib.huff | 202 -- ...bhvkcstcqznkwuhmkwwvrdjviacaricEthers.huff | 47 - ...mxfmambbznmfrsntcscmmocveeDateTimeLib.huff | 517 ----- ...fnwunrsrlqxsbhtmizflbifjcrmxdqCREATE3.huff | 177 -- ...wkphsyuihxlbouwaxpbkeiagInsertionSort.huff | 100 - ...pvqgkfupsuzejejufgqepcfpeyDateTimeLib.huff | 517 ----- ...vhpaiggcjojltrdelmvtrrnvpcuusPausable.huff | 131 -- ...msfvcgannmmwswbxlbvrttkmvnfxjsyErrors.huff | 303 --- ...utylwrboumnhnihgplkcsjdrInsertionSort.huff | 100 - test/auth/Auth.t.sol | 2 +- test/auth/NonPayable.t.sol | 2 +- test/auth/OnlyContract.t.sol | 2 +- test/auth/Owned.t.sol | 2 +- test/auth/RolesAuthority.t.sol | 2 +- test/data-structures/Arrays.t.sol | 2 +- test/data-structures/Bytes.t.sol | 2 +- test/data-structures/Hashmap.t.sol | 2 +- test/factories/Factory.t.sol | 2 +- test/factories/ProxyFactory.t.sol | 2 +- test/math/FixedPointMath.t.sol | 2 +- test/math/Math.t.sol | 2 +- test/math/SafeMath.t.sol | 2 +- test/math/Trigonometry.t.sol | 2 +- test/mechanisms/huff-clones/HuffClone.t.sol | 2 +- .../huff-clones/HuffCloneFactory.t.sol | 2 +- test/mechanisms/huff-clones/Interfaces.sol | 2 +- test/mechanisms/huff-vrgda/LinearVRGDA.t.sol | 2 +- .../mechanisms/huff-vrgda/LogisticVRGDA.t.sol | 2 +- .../huff-vrgda/utils/SignedWadMath.sol | 2 +- test/proxies/Clones.t.sol | 2 +- test/proxies/ERC1967Proxy.t.sol | 2 +- test/proxies/mocks/MockBeacon.sol | 2 +- test/proxies/mocks/MockProxiableUUID.sol | 2 +- test/proxies/mocks/MockReturner.sol | 2 +- .../mocks/NotUUPSMockProxiableUUID.sol | 2 +- test/test-utils/FuzzingUtils.sol | 2 +- test/test-utils/NonMatchingSelectorHelper.sol | 2 +- test/tokens/ERC1155.t.sol | 2 +- test/tokens/ERC20.t.sol | 2 +- test/tokens/ERC4626.t.sol | 2 +- test/tokens/ERC721.t.sol | 2 +- test/utils/BitPackLib.t.sol | 2 +- test/utils/CREATE3.t.sol | 2 +- test/utils/Calls.t.sol | 2 +- test/utils/Constants.t.sol | 2 +- test/utils/DateTimeLib.t.sol | 2 +- test/utils/ECDSA.t.sol | 2 +- test/utils/Errors.t.sol | 2 +- test/utils/Ethers.t.sol | 2 +- test/utils/InsertionSort.t.sol | 2 +- test/utils/JumpTableUtil.t.sol | 2 +- test/utils/LibBit.t.sol | 2 +- test/utils/MerkleDistributor.t.sol | 2 +- test/utils/MerkleProofLib.t.sol | 2 +- test/utils/Multicallable.t.sol | 2 +- test/utils/Pausable.t.sol | 2 +- test/utils/ReentrancyGuard.t.sol | 2 +- test/utils/Refunded.t.sol | 2 +- test/utils/SSTORE2.t.sol | 2 +- test/utils/SafeTransferLib.t.sol | 2 +- test/utils/Shuffling.t.sol | 2 +- test/utils/TSOwnable.t.sol | 2 +- .../mocks/MockERC20.sol | 2 +- .../weird-tokens/MissingReturnToken.sol | 2 +- .../weird-tokens/ReturnsFalseToken.sol | 2 +- .../weird-tokens/ReturnsGarbageToken.sol | 2 +- .../weird-tokens/ReturnsTooLittleToken.sol | 2 +- .../weird-tokens/ReturnsTooMuchToken.sol | 2 +- .../weird-tokens/ReturnsTwoToken.sol | 2 +- .../weird-tokens/RevertingToken.sol | 2 +- 146 files changed, 63 insertions(+), 23546 deletions(-) delete mode 100644 src/auth/__TEMP__bcbtcjlsalfjomvpsarxoeqmfengiahvOwned.huff delete mode 100644 src/auth/__TEMP__ecksuksjnrubnscbigchdduxlqllnuupOnlyContract.huff delete mode 100644 src/auth/__TEMP__esiqrgjqqvwuwnofsrtwqcnwpvegncntNonPayable.huff delete mode 100644 src/auth/__TEMP__jddsbmqfkmmmqoxevqxajvrhicbguifoRolesAuthority.huff delete mode 100644 src/auth/__TEMP__nhzcwzdenfjpzjdeotdemryddmmyhqlqRolesAuthority.huff delete mode 100644 src/auth/__TEMP__nmlzffubaorycdmcbstquohvoehulrstRolesAuthority.huff delete mode 100644 src/auth/__TEMP__uebzhrlgdtvsadoebscpgqfqrmgtsohzNonPayable.huff delete mode 100644 src/auth/__TEMP__zmjetucvgvmqkfekoylppiiwxfdjnbfnRolesAuthority.huff delete mode 100644 src/auth/__TEMP__zqlaafiqnjmdgxfwtecsggrrzgqbnqyqOnlyContract.huff delete mode 100644 src/auth/__TEMP__zvezglymjookpccrxwupfpflpekwphopOwned.huff delete mode 100644 src/data-structures/__TEMP__dbkprxxmslvmupkpkwuxxniuwscdqqrnArrays.huff delete mode 100644 src/data-structures/__TEMP__fvwgxfmgyfyneyghrepikbyjmyskqxskHashmap.huff delete mode 100644 src/data-structures/__TEMP__jqxhhzaaidyagiaawzeyxpvkgxcxwtgqHashmap.huff delete mode 100644 src/data-structures/__TEMP__lwkvhrrmofongwpxrjtworcwgnfqpxluBytes.huff delete mode 100644 src/data-structures/__TEMP__swmivzahxlhrjuiphjztstbcaymhckevArrays.huff delete mode 100644 src/data-structures/__TEMP__wvnaxkgsgqemkcqoqqvognrxtldwtppxBytes.huff delete mode 100644 src/math/__TEMP__agffsybhummgrdmhvrzqoxrnkhupycfeMath.huff delete mode 100644 src/math/__TEMP__gtvxtadnkjdmxsyyimfngsleoolwhcqtSafeMath.huff delete mode 100644 src/math/__TEMP__hbpqkpduhnyeazoevkblfjmhdomwtqwoFixedPointMath.huff delete mode 100644 src/math/__TEMP__ohdnimzopkbndglbmvjbzlrpyrrzphnrTrigonometry.huff delete mode 100644 src/math/__TEMP__qakkodxedbspprhymlfrgxlfepgepcrvTrigonometry.huff delete mode 100644 src/math/__TEMP__qnnyckotyuxpdpeuvffbywnubcftdxsyFixedPointMath.huff delete mode 100644 src/math/__TEMP__qvmazraiuhrdvuoecpapxakdrzpwpmuqMath.huff delete mode 100644 src/math/__TEMP__wqcimbuhetstepqivcpdmtxszazlqpnnSafeMath.huff delete mode 100644 src/mechanisms/huff-clones/__TEMP__hvlmmbwdwsqmdvneonbcfprxtzfbmhkuExampleClone.huff delete mode 100644 src/mechanisms/huff-clones/__TEMP__pgbwefuedeoorfkumjbbbagtfehbslnhExampleClone.huff delete mode 100644 src/mechanisms/huff-clones/__TEMP__xhkqnmmjajsmfrshnyoafedbhvmybxcfExampleClone.huff delete mode 100644 src/mechanisms/huff-clones/__TEMP__xpmxrssqgllfjrqfvrmjmhzvpeefnmpcExampleClone.huff delete mode 100644 src/mechanisms/huff-vrgda/__TEMP__emehkakqdlyztnvsbkuhzfucpimehhtdLogisticVRGDA.huff delete mode 100644 src/mechanisms/huff-vrgda/__TEMP__fldyysnwnrmtgswdmaharirrkhhznvgtLinearVRGDA.huff delete mode 100644 src/proxies/__TEMP__flavwmvnufiarmtrrvilwbhnhmfuxofvClones.huff delete mode 100644 src/proxies/__TEMP__klhwbuerlnsihsjssxbghxugniamuyipERC1967Proxy.huff delete mode 100644 src/proxies/__TEMP__xlwhmiuazdwnqpgoxdvgcsfczvtfymagClones.huff delete mode 100644 src/proxies/__TEMP__zgifhurblgmhozyfyviczblaggscrgixERC1967Proxy.huff delete mode 100644 src/tokens/__TEMP__fztznazwowexesrohcdykwsmvfkclmuyERC20.huff delete mode 100644 src/tokens/__TEMP__olyemymwzenpqjpuukwgitehudafctpwERC20.huff delete mode 100644 src/tokens/__TEMP__oqsfkvbhimsywiqwbdlilqoxezxnqvipERC721.huff delete mode 100644 src/tokens/__TEMP__tdpvmgiyjorautmnplhzvgjsaeubpvhbERC4626.huff delete mode 100644 src/tokens/__TEMP__vvaewlzfkyljuiwoxdrktdnlhsuzsmbhERC721.huff delete mode 100644 src/tokens/__TEMP__zxgqnylgrbytfwvkvdnlnpcvxmcecsliERC4626.huff delete mode 100644 src/utils/__TEMP__ahkbbusaspkdjqohbmhkbfmghcmmpksnCREATE3.huff delete mode 100644 src/utils/__TEMP__ajvxrvsbqwgufgegzhdrxxamgnvfwtnzJumpTableUtil.huff delete mode 100644 src/utils/__TEMP__appuiqwhffqjrpihtljpxmlgbwuzstqlMerkleProofLib.huff delete mode 100644 src/utils/__TEMP__avabubbndjqnadwlvmuebjtdnnpdjprqConstants.huff delete mode 100644 src/utils/__TEMP__bnvxrcqsckqdaprqvhayryuhporeghmzSafeTransferLib.huff delete mode 100644 src/utils/__TEMP__ctwgjphmybkljahoybtnldrrcpneywglECDSA.huff delete mode 100644 src/utils/__TEMP__dabwfcmbyyrjifcrrrqvnmskahrxtfwfPausable.huff delete mode 100644 src/utils/__TEMP__dolvqpolutctxhctjzvajsrpbtpqfvdlCalls.huff delete mode 100644 src/utils/__TEMP__ejbyrnbkhzztmedggubevwdmphskibtxMerkleDistributor.huff delete mode 100644 src/utils/__TEMP__epqcrijckuxiernloalienlasrtffackConstants.huff delete mode 100644 src/utils/__TEMP__eyomwxkixnogyzbecekrqolgmjnwpgibLibBit.huff delete mode 100644 src/utils/__TEMP__fipsesfweqvmnghgiyyjyzxhruyzqbslBitPackLib.huff delete mode 100644 src/utils/__TEMP__flqjyauokblaazsrdhqxfgjsonhnpjloMerkleProofLib.huff delete mode 100644 src/utils/__TEMP__fsghwzbaphyfhugpyejapdmpmaanfaqcTSOwnable.huff delete mode 100644 src/utils/__TEMP__fvsgbbyoimpybpmxmyrddbxuhherfeclBitPackLib.huff delete mode 100644 src/utils/__TEMP__gbfutonvmuwvpsgnhyhrztoimrzkyqskTSOwnable.huff delete mode 100644 src/utils/__TEMP__gzlramplmuvmnsgrxrurevmmugyklixkEthers.huff delete mode 100644 src/utils/__TEMP__hkejoojmditrgmsogdgtpmxmtwqmpdocReentrancyGuard.huff delete mode 100644 src/utils/__TEMP__hutfgjhkcylvhdduoakglqjyfagmmbgbJumpTableUtil.huff delete mode 100644 src/utils/__TEMP__iuxgytjvcjspqzqpxtbelyxicffhqxfrSSTORE2.huff delete mode 100644 src/utils/__TEMP__kfkjwomkxvqpeatpkwmzsmvjaneohelmRefunded.huff delete mode 100644 src/utils/__TEMP__kkfsbfpunncyiouwtmltswyzljambbxxShuffling.huff delete mode 100644 src/utils/__TEMP__ldwwbkwihqrpqdglcwrdylrneycegnebReentrancyGuard.huff delete mode 100644 src/utils/__TEMP__piwyyoypwjyhbfuzsxxekolsbwxgwxsdSSTORE2.huff delete mode 100644 src/utils/__TEMP__ppohrkhyvnxmaxjzqlkackypaopwtytiErrors.huff delete mode 100644 src/utils/__TEMP__prdtsuvrwjmqtxbpjcrrcoacbfeiivquShuffling.huff delete mode 100644 src/utils/__TEMP__qbvbklotqjimwddbdrttqayfxbbmavfvLibBit.huff delete mode 100644 src/utils/__TEMP__qfzbthtrligkzrxhdcwizlbkonnnqqiyCalls.huff delete mode 100644 src/utils/__TEMP__rrvaaiimcokotvnwlrlotlmzautjwxvsMulticallable.huff delete mode 100644 src/utils/__TEMP__ryraejdcasobgumhdtbwarjszpnlvasmECDSA.huff delete mode 100644 src/utils/__TEMP__sjmfwvdxpickfrbtnbbaudfvqefkatoiRefunded.huff delete mode 100644 src/utils/__TEMP__sqowhqjsqxheosskvfeygpuobkhcslnvMerkleDistributor.huff delete mode 100644 src/utils/__TEMP__syuldunwuhcelrjhrahufjtvdthjstmmMulticallable.huff delete mode 100644 src/utils/__TEMP__tvibuicjahwdnvquznelrjppmvqtmvduSafeTransferLib.huff delete mode 100644 src/utils/__TEMP__ubhvkcstcqznkwuhmkwwvrdjviacaricEthers.huff delete mode 100644 src/utils/__TEMP__vamkrwmxfmambbznmfrsntcscmmocveeDateTimeLib.huff delete mode 100644 src/utils/__TEMP__vqfnwunrsrlqxsbhtmizflbifjcrmxdqCREATE3.huff delete mode 100644 src/utils/__TEMP__wiecgaaxwkphsyuihxlbouwaxpbkeiagInsertionSort.huff delete mode 100644 src/utils/__TEMP__wtgpdnpvqgkfupsuzejejufgqepcfpeyDateTimeLib.huff delete mode 100644 src/utils/__TEMP__xllvhpaiggcjojltrdelmvtrrnvpcuusPausable.huff delete mode 100644 src/utils/__TEMP__xmsfvcgannmmwswbxlbvrttkmvnfxjsyErrors.huff delete mode 100644 src/utils/__TEMP__zzxsgvxvutylwrboumnhnihgplkcsjdrInsertionSort.huff diff --git a/.gitmodules b/.gitmodules index 1d8468b9..1f2110ee 100644 --- a/.gitmodules +++ b/.gitmodules @@ -7,4 +7,3 @@ [submodule "lib/foundry-huff"] path = lib/foundry-huff url = https://github.com/huff-language/foundry-huff - branch = md/evm-version-option diff --git a/lib/foundry-huff b/lib/foundry-huff index f027ce6d..bcac40d5 160000 --- a/lib/foundry-huff +++ b/lib/foundry-huff @@ -1 +1 @@ -Subproject commit f027ce6d6f64e553a023f0daa7747ebd70edbeaa +Subproject commit bcac40d5b0950588b30cdf24dff25df080007295 diff --git a/src/auth/__TEMP__bcbtcjlsalfjomvpsarxoeqmfengiahvOwned.huff b/src/auth/__TEMP__bcbtcjlsalfjomvpsarxoeqmfengiahvOwned.huff deleted file mode 100644 index 09840cc6..00000000 --- a/src/auth/__TEMP__bcbtcjlsalfjomvpsarxoeqmfengiahvOwned.huff +++ /dev/null @@ -1,106 +0,0 @@ - -#define macro CONSTRUCTOR() = takes (0) returns (0) { - OWNED_CONSTRUCTOR() -} - -#define macro MAIN() = takes (0) returns (0) { - pc calldataload 0xe0 shr - OWNED_MAIN() - 0x00 dup1 revert -} - - -/// @title Owned -/// @notice SPDX-License-Identifier: MIT -/// @author asnared -/// @notice An single owner authorization module -/// @notice Adapted from - -// Interface -#define function setOwner(address) nonpayable returns () -#define function owner() view returns (address) - -// Events -#define event OwnerUpdated(address indexed user, address indexed newOwner) - -// Storage Slots -#define constant OWNER = FREE_STORAGE_POINTER() - -// CONSTRUCTOR -#define macro OWNED_CONSTRUCTOR() = takes (0) returns (0) { - // Copy the owner into memory - 0x20 // [size] - byte size to copy - 0x20 codesize sub // [offset, size] - offset in the code to copy from - 0x00 // [mem, offset, size] - offset in memory to copy to - codecopy // [] - - // Set the new owner - 0x00 mload // [owner] - dup1 // [owner, owner] - [OWNER] // [OWNER, owner, owner] - sstore // [owner] - - // Emit the owner updated event - caller // [from, owner] - __EVENT_HASH(OwnerUpdated) // [sig, from, owner] - 0x00 0x00 // [0, 0, sig, from, owner] - log3 // [] -} - -/// @notice Only Owner Modifier -#define macro IS_OWNER() = takes (0) returns (0) { - caller // [msg.sender] - [OWNER] sload // [owner, msg.sender] - eq authed jumpi // [authed] - - // Revert otherwise - 0x00 0x00 revert - - authed: -} - -/// @notice Set the Owner -/// @param {owner} [address] - The new owner -#define macro SET_OWNER() = takes (0) returns (0) { - // Check that the caller is authorized - IS_OWNER() - - // Set the new owner - 0x04 calldataload // [newOwner] - dup1 // [newOwner, newOwner] - [OWNER] sstore // [newOwner] - - // Emit the owner updated event - caller // [from, newOwner] - __EVENT_HASH(OwnerUpdated) // [sig, from, newOwner] - 0x00 0x00 // [0, 32, sig, from, newOwner] - log3 // [] - - stop -} - -/// @notice Get the owner of the contract -/// @return {owner} [address] - The owner of the contract -#define macro OWNER() = takes (0) returns (0) { - [OWNER] sload // [owner] - 0x00 mstore // [] - 0x20 0x00 return -} - -/// @notice Main Function Dispatcher -#define macro OWNED_MAIN() = takes (1) returns (1) { - // Input Stack: [function_selector] - - dup1 __FUNC_SIG(setOwner) eq set_owner jumpi - dup1 __FUNC_SIG(owner) eq owner jumpi - - // Bubble up to parent macro - no_match jump - - set_owner: - SET_OWNER() - owner: - OWNER() - - no_match: -} \ No newline at end of file diff --git a/src/auth/__TEMP__ecksuksjnrubnscbigchdduxlqllnuupOnlyContract.huff b/src/auth/__TEMP__ecksuksjnrubnscbigchdduxlqllnuupOnlyContract.huff deleted file mode 100644 index 20350e76..00000000 --- a/src/auth/__TEMP__ecksuksjnrubnscbigchdduxlqllnuupOnlyContract.huff +++ /dev/null @@ -1,26 +0,0 @@ -#define macro MAIN() = takes(0) returns(0) { - ONLY_CONTRACT() - 0x00 0x00 log0 // anonymous log - 0x01 0x00 mstore - 0x20 0x00 return -} - - -/// @title OnlyContract -/// @notice SPDX-License-Identifier: MIT -/// @author asnared -/// @notice Reverts if the caller is not a contract with a tx.origin check. - -/// @notice Reverts if the caller is not a contract using tx.origin. -/// @dev WARNING: This is an anti-pattern and prevents interoperability. -/// Additionally, this will become ineffective once either EIP-2938 OR EIP-4337 account abstraction's are implemented. -/// EIP-3074 is another concern as it essentially allows users to delegate control of an EOA to a contract. -/// Additionally, users of wallets like argent, authereum and gnosis multi-sigs are able to "bypass" this access control. -#define macro ONLY_CONTRACT() = takes (0) returns (0) { - caller // [msg.sender] - origin // [tx.origin, msg.sender] - eq iszero // [tx.origin != msg.sender] - continue jumpi // [] - 0x00 dup1 revert // [] - continue: -} diff --git a/src/auth/__TEMP__esiqrgjqqvwuwnofsrtwqcnwpvegncntNonPayable.huff b/src/auth/__TEMP__esiqrgjqqvwuwnofsrtwqcnwpvegncntNonPayable.huff deleted file mode 100644 index 922ee3d6..00000000 --- a/src/auth/__TEMP__esiqrgjqqvwuwnofsrtwqcnwpvegncntNonPayable.huff +++ /dev/null @@ -1,27 +0,0 @@ -#define macro MAIN() = takes(0) returns(0) { - NON_PAYABLE() - 0x00 0x00 log0 // anonymous log - 0x01 0x00 mstore - 0x20 0x00 return -} - - -/// @title Non Payable -/// @notice SPDX-License-Identifier: MIT -/// @author asnared -/// @notice Simple macro to revert if a call has a value - -#include "../utils/Errors.huff" - -// "NON_PAYABLE" Revert Message String -#define constant NON_PAYABLE_ERROR = 0xb4e4f4e5f50415941424c45000000000000000000000000000000000000000000 -#define constant NON_PAYABLE_LENGTH = 0x0b - -/// @notice Reverts if the call has a non-zero value -/// @notice Reverts with message "NON_PAYABLE" -#define macro NON_PAYABLE() = takes (0) returns (0) { - [NON_PAYABLE_ERROR] // ["NON_PAYABLE"] - [NON_PAYABLE_LENGTH] // [11 (length), "NON_PAYABLE"] - callvalue iszero // [msg.value == 0, 11 (length), "NON_PAYABLE"] - REQUIRE() // [] -} diff --git a/src/auth/__TEMP__jddsbmqfkmmmqoxevqxajvrhicbguifoRolesAuthority.huff b/src/auth/__TEMP__jddsbmqfkmmmqoxevqxajvrhicbguifoRolesAuthority.huff deleted file mode 100644 index a9f4551e..00000000 --- a/src/auth/__TEMP__jddsbmqfkmmmqoxevqxajvrhicbguifoRolesAuthority.huff +++ /dev/null @@ -1,314 +0,0 @@ - -#define macro CONSTRUCTOR() = takes (0) returns (0) { - AUTH_CONSTRUCTOR() -} - -#define macro MAIN() = takes (0) returns (0) { - pc calldataload 0xe0 shr - ROLES_AUTHORITY_MAIN() - 0x00 dup1 revert -} - - -/// @title Roles Authority -/// @notice SPDX-License-Identifier: MIT -/// @author asnared -/// @notice A Role based Authority that supports up to 256 roles -/// @notice Adapted from Solmate ( -/// @notice A Role based Authority that supports up to 256 roles -/// @notice Adapted from Solmate ( -/// @notice A Role based Authority that supports up to 256 roles -/// @notice Adapted from Solmate ( -/// @notice Simple macro to revert if a call has a value - -#include "../utils/Errors.huff" - -// "NON_PAYABLE" Revert Message String -#define constant NON_PAYABLE_ERROR = 0xb4e4f4e5f50415941424c45000000000000000000000000000000000000000000 -#define constant NON_PAYABLE_LENGTH = 0x0b - -/// @notice Reverts if the call has a non-zero value -/// @notice Reverts with message "NON_PAYABLE" -#define macro NON_PAYABLE() = takes (0) returns (0) { - [NON_PAYABLE_ERROR] // ["NON_PAYABLE"] - [NON_PAYABLE_LENGTH] // [11 (length), "NON_PAYABLE"] - callvalue iszero // [msg.value == 0, 11 (length), "NON_PAYABLE"] - REQUIRE() // [] -} diff --git a/src/auth/__TEMP__zmjetucvgvmqkfekoylppiiwxfdjnbfnRolesAuthority.huff b/src/auth/__TEMP__zmjetucvgvmqkfekoylppiiwxfdjnbfnRolesAuthority.huff deleted file mode 100644 index a9f4551e..00000000 --- a/src/auth/__TEMP__zmjetucvgvmqkfekoylppiiwxfdjnbfnRolesAuthority.huff +++ /dev/null @@ -1,314 +0,0 @@ - -#define macro CONSTRUCTOR() = takes (0) returns (0) { - AUTH_CONSTRUCTOR() -} - -#define macro MAIN() = takes (0) returns (0) { - pc calldataload 0xe0 shr - ROLES_AUTHORITY_MAIN() - 0x00 dup1 revert -} - - -/// @title Roles Authority -/// @notice SPDX-License-Identifier: MIT -/// @author asnared -/// @notice A Role based Authority that supports up to 256 roles -/// @notice Adapted from Solmate ( -/// @notice Reverts if the caller is not a contract with a tx.origin check. - -/// @notice Reverts if the caller is not a contract using tx.origin. -/// @dev WARNING: This is an anti-pattern and prevents interoperability. -/// Additionally, this will become ineffective once either EIP-2938 OR EIP-4337 account abstraction's are implemented. -/// EIP-3074 is another concern as it essentially allows users to delegate control of an EOA to a contract. -/// Additionally, users of wallets like argent, authereum and gnosis multi-sigs are able to "bypass" this access control. -#define macro ONLY_CONTRACT() = takes (0) returns (0) { - caller // [msg.sender] - origin // [tx.origin, msg.sender] - eq iszero // [tx.origin != msg.sender] - continue jumpi // [] - 0x00 dup1 revert // [] - continue: -} diff --git a/src/auth/__TEMP__zvezglymjookpccrxwupfpflpekwphopOwned.huff b/src/auth/__TEMP__zvezglymjookpccrxwupfpflpekwphopOwned.huff deleted file mode 100644 index 09840cc6..00000000 --- a/src/auth/__TEMP__zvezglymjookpccrxwupfpflpekwphopOwned.huff +++ /dev/null @@ -1,106 +0,0 @@ - -#define macro CONSTRUCTOR() = takes (0) returns (0) { - OWNED_CONSTRUCTOR() -} - -#define macro MAIN() = takes (0) returns (0) { - pc calldataload 0xe0 shr - OWNED_MAIN() - 0x00 dup1 revert -} - - -/// @title Owned -/// @notice SPDX-License-Identifier: MIT -/// @author asnared -/// @notice An single owner authorization module -/// @notice Adapted from - -// Interface -#define function setOwner(address) nonpayable returns () -#define function owner() view returns (address) - -// Events -#define event OwnerUpdated(address indexed user, address indexed newOwner) - -// Storage Slots -#define constant OWNER = FREE_STORAGE_POINTER() - -// CONSTRUCTOR -#define macro OWNED_CONSTRUCTOR() = takes (0) returns (0) { - // Copy the owner into memory - 0x20 // [size] - byte size to copy - 0x20 codesize sub // [offset, size] - offset in the code to copy from - 0x00 // [mem, offset, size] - offset in memory to copy to - codecopy // [] - - // Set the new owner - 0x00 mload // [owner] - dup1 // [owner, owner] - [OWNER] // [OWNER, owner, owner] - sstore // [owner] - - // Emit the owner updated event - caller // [from, owner] - __EVENT_HASH(OwnerUpdated) // [sig, from, owner] - 0x00 0x00 // [0, 0, sig, from, owner] - log3 // [] -} - -/// @notice Only Owner Modifier -#define macro IS_OWNER() = takes (0) returns (0) { - caller // [msg.sender] - [OWNER] sload // [owner, msg.sender] - eq authed jumpi // [authed] - - // Revert otherwise - 0x00 0x00 revert - - authed: -} - -/// @notice Set the Owner -/// @param {owner} [address] - The new owner -#define macro SET_OWNER() = takes (0) returns (0) { - // Check that the caller is authorized - IS_OWNER() - - // Set the new owner - 0x04 calldataload // [newOwner] - dup1 // [newOwner, newOwner] - [OWNER] sstore // [newOwner] - - // Emit the owner updated event - caller // [from, newOwner] - __EVENT_HASH(OwnerUpdated) // [sig, from, newOwner] - 0x00 0x00 // [0, 32, sig, from, newOwner] - log3 // [] - - stop -} - -/// @notice Get the owner of the contract -/// @return {owner} [address] - The owner of the contract -#define macro OWNER() = takes (0) returns (0) { - [OWNER] sload // [owner] - 0x00 mstore // [] - 0x20 0x00 return -} - -/// @notice Main Function Dispatcher -#define macro OWNED_MAIN() = takes (1) returns (1) { - // Input Stack: [function_selector] - - dup1 __FUNC_SIG(setOwner) eq set_owner jumpi - dup1 __FUNC_SIG(owner) eq owner jumpi - - // Bubble up to parent macro - no_match jump - - set_owner: - SET_OWNER() - owner: - OWNER() - - no_match: -} \ No newline at end of file diff --git a/src/data-structures/__TEMP__dbkprxxmslvmupkpkwuxxniuwscdqqrnArrays.huff b/src/data-structures/__TEMP__dbkprxxmslvmupkpkwuxxniuwscdqqrnArrays.huff deleted file mode 100644 index d63bae3b..00000000 --- a/src/data-structures/__TEMP__dbkprxxmslvmupkpkwuxxniuwscdqqrnArrays.huff +++ /dev/null @@ -1,121 +0,0 @@ -// Sets an array from calldata. -// sig: 0x226ce6b7 -#define function setArrayFromCalldata(uint256[]) view returns () - -// Returns an array. -// sig: 0xde9ee75c -#define function loadArray() view returns (uint256[] memory) - -#define constant LOCATION = FREE_STORAGE_POINTER() - -#define macro SET_FROM_CALLDATA() = takes(0) returns(0) { - [LOCATION] 0x04 - SET_ARRAY_FROM_CALLDATA() - stop -} - - -// Store the value for the given key. -#define macro RETURN() = takes(0) returns(0) { - [LOCATION] - RETURN_ARRAY(0x80) -} - -/* Main Macro - The contract entrypoint */ -#define macro MAIN() = takes(0) returns (0) { - // Identify which function is being called using the 4 byte function signature - 0x00 calldataload 0xE0 shr - dup1 __FUNC_SIG(setArrayFromCalldata) eq set_from_calldata jumpi - dup1 __FUNC_SIG(loadArray) eq load jumpi - - // Revert if otherwise - 0x00 0x00 revert - - set_from_calldata: - SET_FROM_CALLDATA() - load: - RETURN() -} - - -/// @title Arrays -/// @notice SPDX-License-Identifier: MIT -/// @author exp-table -/// @notice Array utility library for Solidity contracts - -/// @notice Sets an array in storage from calldata. -/// Note that since no assumptions is made regarding the context in which -/// this function is called, the position of the encoded array in the calldata -/// has to be specified. -#define macro SET_ARRAY_FROM_CALLDATA() = takes(2) returns (0) { - // Input stack: [calldata_start, slot] - // skip size of one individual element - 0x20 add // [calldata_start+0x20, slot] - dup1 0x20 add swap1 // [calldata_start+0x20, calldata_start+0x40, slot] - // load length - calldataload // [length, calldata_offset, slot] - // store length at slot - dup1 dup4 // [slot, length, length, calldata_offset, slot] - sstore // [length, calldata_offset, slot] - - // store slot in memory scratch space and compute hash - dup3 0x00 mstore // [length, calldata_offset, slot] - 0x20 0x00 sha3 // [sha3(slot), length, ,calldata_offset slot] - - // loop and store every element in slot sha3(slot)+n - 0x00 // [index(0), sha3(slot), length, calldata_offset, slot] - start jump - continue: - // if index == length -> it's over - eq end jumpi // [index(i), sha3(slot), length, calldata_offset, slot] - start: - // load from calldata - dup1 0x20 mul dup5 add calldataload // [array(i), index(i), sha3(slot), length, calldata_offset, slot] - // store at slot sha3(slot)+index - dup3 dup3 add sstore // [index(i), sha3(slot), length, calldata_offset, slot] - // inc index - 0x01 add // [index(i+1), sha3(slot), length, calldata_offset, slot] - dup3 dup2 // [index(i+1), length, index(i+1), sha3(slot), length, calldata_offset, slot] - continue jump - - end: -} - -/// @notice Returns an array in memory specified at {mem_ptr} -#define macro RETURN_ARRAY(mem_ptr) = takes(1) returns (0) { - // Input stack: [slot] - - // store the size of each element in memory - 0x20 mstore // [slot] - // [mem_ptr, slot] - // load length from storage - dup2 sload dup1 // [length, length, curr_mem_ptr, slot] - // store length in memory - swap2 0x20 add // [curr_mem_ptr+0x20, length, length, slot] - swap1 dup2 mstore // [curr_mem_ptr, length, slot] - - // store slot in memory scratch space and compute hash - swap2 0x00 mstore // [length, curr_mem_ptr] - 0x20 0x00 sha3 swap2 // [curr_mem_ptr, length, sha3(slot)] - - // loop and load every element in slot sha3(slot)+n - 0x00 start jump // [index(0), curr_mem_ptr, length, sha3(slot)] - continue: - // if index == length -> it's over - eq end jumpi // [index(i), curr_mem_ptr, length, sha3(slot)] - start: - // load from storage ; add index to sha3(slot) - dup1 dup5 add sload // [array(i), index(i), curr_mem_ptr, length, sha3(slot)] - // store in memory - swap1 swap2 0x20 add // [curr_mem_ptr+0x20, array(i), index(i), length, sha3(slot)] - dup1 swap2 swap1 mstore // [curr_mem_ptr+0x20, index(i), length, sha3(slot)] - // update index - swap1 0x01 add // [index(i+1), curr_mem_ptr, length, sha3(slot)] - dup1 dup4 - continue jump - - end: - // size of data to return = size of individual element + array length + encoded elements - swap2 0x02 add 0x05 shl // [size, curr_mem_ptr, index(i), sha3(slot)] - return -} \ No newline at end of file diff --git a/src/data-structures/__TEMP__fvwgxfmgyfyneyghrepikbyjmyskqxskHashmap.huff b/src/data-structures/__TEMP__fvwgxfmgyfyneyghrepikbyjmyskqxskHashmap.huff deleted file mode 100644 index f603cb4c..00000000 --- a/src/data-structures/__TEMP__fvwgxfmgyfyneyghrepikbyjmyskqxskHashmap.huff +++ /dev/null @@ -1,317 +0,0 @@ -// Returns the slot value for the given key. -// sig: 0x437b8ad6 -#define function loadElement(bytes32) view returns (bytes32) - -// Returns the slot value by hashing the given keys. -// sig: 0xf268de10 -#define function loadElementFromKeys(bytes32, bytes32) view returns (bytes32) - -// Returns the slot value by hashing the given slot and two keys. -// sig: 0xef5b4768 -#define function loadElementFromKeys2D(bytes32, bytes32, bytes32) view returns (bytes32) - -// Returns the slot value by hashing the given slot and three keys. -// sig: 0x0cc703f5 -#define function loadElementFromKeys3D(bytes32, bytes32, bytes32, bytes32) view returns (bytes32) - -// Stores the value for the given key. -// sig: 0x376caf9f -#define function storeElement(bytes32 key, bytes32 value) nonpayable returns () - -// Stores the value for the given keys -// sig: 0x2fdb44d8 -#define function storeElementFromKeys(bytes32 key1, bytes32 key2, bytes32 value) nonpayable returns () - -// Stores the value given a slot and two keys -// sig: 0x64fab984 -#define function storeElementFromKeys2D( - bytes32 slot, - bytes32 key1, - bytes32 key2, - bytes32 value -) nonpayable returns () - -// Stores the value given a slot and three keys -// sig: 0xd3b12314 -#define function storeElementFromKeys3D( - bytes32 slot, - bytes32 key1, - bytes32 key2, - bytes32 key3, - bytes32 value -) nonpayable returns () - -#define constant LOCATION = FREE_STORAGE_POINTER() - -// Get the value for the given key. -#define macro GET() = takes(0) returns(0) { - 0x04 calldataload - LOAD_ELEMENT(0x00) - 0x00 mstore - 0x20 0x00 return -} - -// Get the value for the given keys. -#define macro GET_FROM_KEYS() = takes(0) returns(0) { - 0x24 calldataload - 0x04 calldataload - LOAD_ELEMENT_FROM_KEYS(0x00) - 0x00 mstore - 0x20 0x00 return -} - -// Get the value for the given slot and two keys -#define macro GET_FROM_KEYS_2D() = takes(0) returns(0) { - 0x44 calldataload - 0x24 calldataload - 0x04 calldataload - LOAD_ELEMENT_FROM_KEYS_2D(0x00) - 0x00 mstore - 0x20 0x00 return -} - -// Get the value for the given slot and three keys -#define macro GET_FROM_KEYS_3D() = takes(0) returns(0) { - 0x64 calldataload - 0x44 calldataload - 0x24 calldataload - 0x04 calldataload - LOAD_ELEMENT_FROM_KEYS_3D(0x00) - 0x00 mstore - 0x20 0x00 return -} - -// Store the value for the given key. -#define macro STORE() = takes(0) returns(0) { - 0x24 calldataload - 0x04 calldataload - STORE_ELEMENT(0x00) - stop -} - -// Store the value for the given key. -#define macro STORE_FROM_KEYS() = takes(0) returns(0) { - 0x44 calldataload - 0x24 calldataload - 0x04 calldataload - STORE_ELEMENT_FROM_KEYS(0x00) - stop -} - -// Store the value for the given slot and two keys. -#define macro STORE_FROM_KEYS_2D() = takes(0) returns(0) { - 0x64 calldataload - 0x44 calldataload - 0x24 calldataload - 0x04 calldataload - STORE_ELEMENT_FROM_KEYS_2D(0x00) - stop -} - -// Store the value for the given slot and three keys. -#define macro STORE_FROM_KEYS_3D() = takes(0) returns(0) { - 0x84 calldataload - 0x64 calldataload - 0x44 calldataload - 0x24 calldataload - 0x04 calldataload - STORE_ELEMENT_FROM_KEYS_3D(0x00) - stop -} - -// Main Macro - The contract entrypoint -#define macro MAIN() = takes(0) returns (0) { - // Identify which function is being called using the 4 byte function signature - pc calldataload 0xE0 shr - - dup1 __FUNC_SIG(loadElement) eq load_element jumpi - dup1 __FUNC_SIG(loadElementFromKeys) eq load_element_from_keys jumpi - dup1 __FUNC_SIG(loadElementFromKeys2D) eq load_element_from_keys_2d jumpi - dup1 __FUNC_SIG(loadElementFromKeys3D) eq load_element_from_keys_3d jumpi - dup1 __FUNC_SIG(storeElement) eq store_element jumpi - dup1 __FUNC_SIG(storeElementFromKeys) eq store_element_from_keys jumpi - dup1 __FUNC_SIG(storeElementFromKeys2D) eq store_element_from_keys_2d jumpi - dup1 __FUNC_SIG(storeElementFromKeys3D) eq store_element_from_keys_3d jumpi - - // Revert if otherwise - 0x00 dup1 revert - - load_element: - GET() - load_element_from_keys: - GET_FROM_KEYS() - load_element_from_keys_2d: - GET_FROM_KEYS_2D() - load_element_from_keys_3d: - GET_FROM_KEYS_3D() - store_element: - STORE() - store_element_from_keys: - STORE_FROM_KEYS() - store_element_from_keys_2d: - STORE_FROM_KEYS_2D() - store_element_from_keys_3d: - STORE_FROM_KEYS_3D() -} - - -/// @title HashMap -/// @notice SPDX-License-Identifier: MIT -/// @author asnared -/// @notice A Module Encapsulating HashMap Methods -/// @notice Adapted from - -/// @notice Given a piece of data (ie an address), hash it, generating the storage slot for a hashmap. -#define macro GET_SLOT_FROM_KEY(mem_ptr) = takes(1) returns (1) { - // Input stack: [key] - // Load the data into memory and hash it, while preserving the memory location. - // [, key] - mstore // [] - - // Hash the data, generating a key. - 0x20 // [32] - // [, 32] - sha3 // [slot] -} - -/// @notice Given two keys (ie a slot and a key), hash them together, generating a slot for a secondary hashmap. -#define macro GET_SLOT_FROM_KEYS(mem_ptr) = takes(2) returns (1) { - // Input stack: [slot, key] - // Load the data into memory. - 0x20 add // [ + 32, slot, key] - mstore // [key] - // [, key] - mstore // [] - - // Hash the data, generating a slot. - 0x40 // [64] - // [, 64] - sha3 // [slot] -} - -/// @notice Calculate the slot from two keys -#define macro GET_SLOT_FROM_KEYS_2D(mem_ptr) = takes(3) returns (1) { - // Input stack: [slot, key1, key2] - // Load the data into memory - 0x20 add // [ + 32, slot, key1, key2] - mstore // [key1, key2] - - // next byte - // [, key1, key2] - mstore // [key2] - - 0x40 // [0x40, key2] - // [, 0x40, key2] - sha3 // [hash, key2] - - // concat the two keys - 0x20 add // [ + 32, hash, key2] put hash in memory - mstore // [key2] - - // next byte - // [, key2] - mstore // [] - - // Hash the data, generating a slot. - 0x40 // [0x40] - // [, 0x40] - sha3 // [slot] -} - -/// @notice Calculate the slot from three keys -#define macro GET_SLOT_FROM_KEYS_3D(mem_ptr) = takes(4) returns (1) { - // Input stack: [slot, key1, key2, key3] - // Load the data into memory - 0x20 add // [ + 32, slot, key1, key2, key3] - swap1 dup2 // [ + 32, slot, + 32, key1, key2, key3] - mstore // [ + 32, key1, key2, key3] - - swap1 // [, key1, + 32, key2, key3] - mstore // [ + 32, key2, key3] - - 0x40 // [0x40, + 32, key2, key3] - // [, 0x40, + 32, key2, key3] - sha3 // [slot1, + 32, key2, key3] - - // concat the first two keys - dup2 // [ + 32, slot1, + 32, key2, key3] put slot1 in memory - mstore // [ + 32, key2, key3] - - // put key2 in memory, before slot1 - swap1 // [key2, + 32, key3] - // [, key2, + 32, key3] - mstore // [key3] - - 0x40 // [0x40, + 32, key3] - // [, 0x40, + 32, key3] - sha3 // [slot2, + 32, key3] - - // concat with the third key - swap1 // [ + 32, slot2, key3] put slot2 in memory - mstore // [key3] - - // put key3 in memory, before slot2 - // [, key3] - mstore // [] - - // Hash the data, generating the final slot3 - 0x40 // [0x40] - // [, 0x40] - sha3 // [slot3] -} - -/// @notice Load an element onto the stack from a key -#define macro LOAD_ELEMENT(mem_ptr) = takes(1) returns(1) { - // Input stack: [key] - GET_SLOT_FROM_KEY() // [slot] - sload // [value] -} - -/// @notice Load an element onto the stack from two keys -#define macro LOAD_ELEMENT_FROM_KEYS(mem_ptr) = takes(2) returns(1) { - // Input stack: [key1, key2] - GET_SLOT_FROM_KEYS() // [slot] - sload // [value] -} - -/// @notice Load an element onto the stack from a slot and two keys -#define macro LOAD_ELEMENT_FROM_KEYS_2D(mem_ptr) = takes(3) returns(1) { - // Input stack: [slot, key1, key2] - GET_SLOT_FROM_KEYS_2D() // [slot] - sload // [value] -} - -/// @notice Load an element onto the stack from a slot and three keys -#define macro LOAD_ELEMENT_FROM_KEYS_3D(mem_ptr) = takes(4) returns(1) { - // Input stack: [slot, key1, key2, key3] - GET_SLOT_FROM_KEYS_3D() // [slot] - sload // [value] -} - -/// @notice Store an element from a key -#define macro STORE_ELEMENT(mem_ptr) = takes(2) returns(0) { - // Input stack: [key, value] - GET_SLOT_FROM_KEY() // [slot, value] - sstore // [] -} - -/// @notice Store an element from two keys -#define macro STORE_ELEMENT_FROM_KEYS(mem_ptr) = takes(3) returns (0) { - // Input stack: [key1, key2, value] - GET_SLOT_FROM_KEYS() // [slot, value] - sstore // [] -} - -/// @notice Store an element from a slot and two keys -#define macro STORE_ELEMENT_FROM_KEYS_2D(mem_ptr) = takes(4) returns (0) { - // Input stack: [slot, key1, key2, value] - GET_SLOT_FROM_KEYS_2D() // [slot, value] - sstore // [] -} - -/// @notice Store an element from a slot and three keys -#define macro STORE_ELEMENT_FROM_KEYS_3D(mem_ptr) = takes(5) returns (0) { - // Input stack: [slot, key1, key2, key3, value] - GET_SLOT_FROM_KEYS_3D() // [slot, value] - sstore // [] -} \ No newline at end of file diff --git a/src/data-structures/__TEMP__jqxhhzaaidyagiaawzeyxpvkgxcxwtgqHashmap.huff b/src/data-structures/__TEMP__jqxhhzaaidyagiaawzeyxpvkgxcxwtgqHashmap.huff deleted file mode 100644 index f603cb4c..00000000 --- a/src/data-structures/__TEMP__jqxhhzaaidyagiaawzeyxpvkgxcxwtgqHashmap.huff +++ /dev/null @@ -1,317 +0,0 @@ -// Returns the slot value for the given key. -// sig: 0x437b8ad6 -#define function loadElement(bytes32) view returns (bytes32) - -// Returns the slot value by hashing the given keys. -// sig: 0xf268de10 -#define function loadElementFromKeys(bytes32, bytes32) view returns (bytes32) - -// Returns the slot value by hashing the given slot and two keys. -// sig: 0xef5b4768 -#define function loadElementFromKeys2D(bytes32, bytes32, bytes32) view returns (bytes32) - -// Returns the slot value by hashing the given slot and three keys. -// sig: 0x0cc703f5 -#define function loadElementFromKeys3D(bytes32, bytes32, bytes32, bytes32) view returns (bytes32) - -// Stores the value for the given key. -// sig: 0x376caf9f -#define function storeElement(bytes32 key, bytes32 value) nonpayable returns () - -// Stores the value for the given keys -// sig: 0x2fdb44d8 -#define function storeElementFromKeys(bytes32 key1, bytes32 key2, bytes32 value) nonpayable returns () - -// Stores the value given a slot and two keys -// sig: 0x64fab984 -#define function storeElementFromKeys2D( - bytes32 slot, - bytes32 key1, - bytes32 key2, - bytes32 value -) nonpayable returns () - -// Stores the value given a slot and three keys -// sig: 0xd3b12314 -#define function storeElementFromKeys3D( - bytes32 slot, - bytes32 key1, - bytes32 key2, - bytes32 key3, - bytes32 value -) nonpayable returns () - -#define constant LOCATION = FREE_STORAGE_POINTER() - -// Get the value for the given key. -#define macro GET() = takes(0) returns(0) { - 0x04 calldataload - LOAD_ELEMENT(0x00) - 0x00 mstore - 0x20 0x00 return -} - -// Get the value for the given keys. -#define macro GET_FROM_KEYS() = takes(0) returns(0) { - 0x24 calldataload - 0x04 calldataload - LOAD_ELEMENT_FROM_KEYS(0x00) - 0x00 mstore - 0x20 0x00 return -} - -// Get the value for the given slot and two keys -#define macro GET_FROM_KEYS_2D() = takes(0) returns(0) { - 0x44 calldataload - 0x24 calldataload - 0x04 calldataload - LOAD_ELEMENT_FROM_KEYS_2D(0x00) - 0x00 mstore - 0x20 0x00 return -} - -// Get the value for the given slot and three keys -#define macro GET_FROM_KEYS_3D() = takes(0) returns(0) { - 0x64 calldataload - 0x44 calldataload - 0x24 calldataload - 0x04 calldataload - LOAD_ELEMENT_FROM_KEYS_3D(0x00) - 0x00 mstore - 0x20 0x00 return -} - -// Store the value for the given key. -#define macro STORE() = takes(0) returns(0) { - 0x24 calldataload - 0x04 calldataload - STORE_ELEMENT(0x00) - stop -} - -// Store the value for the given key. -#define macro STORE_FROM_KEYS() = takes(0) returns(0) { - 0x44 calldataload - 0x24 calldataload - 0x04 calldataload - STORE_ELEMENT_FROM_KEYS(0x00) - stop -} - -// Store the value for the given slot and two keys. -#define macro STORE_FROM_KEYS_2D() = takes(0) returns(0) { - 0x64 calldataload - 0x44 calldataload - 0x24 calldataload - 0x04 calldataload - STORE_ELEMENT_FROM_KEYS_2D(0x00) - stop -} - -// Store the value for the given slot and three keys. -#define macro STORE_FROM_KEYS_3D() = takes(0) returns(0) { - 0x84 calldataload - 0x64 calldataload - 0x44 calldataload - 0x24 calldataload - 0x04 calldataload - STORE_ELEMENT_FROM_KEYS_3D(0x00) - stop -} - -// Main Macro - The contract entrypoint -#define macro MAIN() = takes(0) returns (0) { - // Identify which function is being called using the 4 byte function signature - pc calldataload 0xE0 shr - - dup1 __FUNC_SIG(loadElement) eq load_element jumpi - dup1 __FUNC_SIG(loadElementFromKeys) eq load_element_from_keys jumpi - dup1 __FUNC_SIG(loadElementFromKeys2D) eq load_element_from_keys_2d jumpi - dup1 __FUNC_SIG(loadElementFromKeys3D) eq load_element_from_keys_3d jumpi - dup1 __FUNC_SIG(storeElement) eq store_element jumpi - dup1 __FUNC_SIG(storeElementFromKeys) eq store_element_from_keys jumpi - dup1 __FUNC_SIG(storeElementFromKeys2D) eq store_element_from_keys_2d jumpi - dup1 __FUNC_SIG(storeElementFromKeys3D) eq store_element_from_keys_3d jumpi - - // Revert if otherwise - 0x00 dup1 revert - - load_element: - GET() - load_element_from_keys: - GET_FROM_KEYS() - load_element_from_keys_2d: - GET_FROM_KEYS_2D() - load_element_from_keys_3d: - GET_FROM_KEYS_3D() - store_element: - STORE() - store_element_from_keys: - STORE_FROM_KEYS() - store_element_from_keys_2d: - STORE_FROM_KEYS_2D() - store_element_from_keys_3d: - STORE_FROM_KEYS_3D() -} - - -/// @title HashMap -/// @notice SPDX-License-Identifier: MIT -/// @author asnared -/// @notice A Module Encapsulating HashMap Methods -/// @notice Adapted from - -/// @notice Given a piece of data (ie an address), hash it, generating the storage slot for a hashmap. -#define macro GET_SLOT_FROM_KEY(mem_ptr) = takes(1) returns (1) { - // Input stack: [key] - // Load the data into memory and hash it, while preserving the memory location. - // [, key] - mstore // [] - - // Hash the data, generating a key. - 0x20 // [32] - // [, 32] - sha3 // [slot] -} - -/// @notice Given two keys (ie a slot and a key), hash them together, generating a slot for a secondary hashmap. -#define macro GET_SLOT_FROM_KEYS(mem_ptr) = takes(2) returns (1) { - // Input stack: [slot, key] - // Load the data into memory. - 0x20 add // [ + 32, slot, key] - mstore // [key] - // [, key] - mstore // [] - - // Hash the data, generating a slot. - 0x40 // [64] - // [, 64] - sha3 // [slot] -} - -/// @notice Calculate the slot from two keys -#define macro GET_SLOT_FROM_KEYS_2D(mem_ptr) = takes(3) returns (1) { - // Input stack: [slot, key1, key2] - // Load the data into memory - 0x20 add // [ + 32, slot, key1, key2] - mstore // [key1, key2] - - // next byte - // [, key1, key2] - mstore // [key2] - - 0x40 // [0x40, key2] - // [, 0x40, key2] - sha3 // [hash, key2] - - // concat the two keys - 0x20 add // [ + 32, hash, key2] put hash in memory - mstore // [key2] - - // next byte - // [, key2] - mstore // [] - - // Hash the data, generating a slot. - 0x40 // [0x40] - // [, 0x40] - sha3 // [slot] -} - -/// @notice Calculate the slot from three keys -#define macro GET_SLOT_FROM_KEYS_3D(mem_ptr) = takes(4) returns (1) { - // Input stack: [slot, key1, key2, key3] - // Load the data into memory - 0x20 add // [ + 32, slot, key1, key2, key3] - swap1 dup2 // [ + 32, slot, + 32, key1, key2, key3] - mstore // [ + 32, key1, key2, key3] - - swap1 // [, key1, + 32, key2, key3] - mstore // [ + 32, key2, key3] - - 0x40 // [0x40, + 32, key2, key3] - // [, 0x40, + 32, key2, key3] - sha3 // [slot1, + 32, key2, key3] - - // concat the first two keys - dup2 // [ + 32, slot1, + 32, key2, key3] put slot1 in memory - mstore // [ + 32, key2, key3] - - // put key2 in memory, before slot1 - swap1 // [key2, + 32, key3] - // [, key2, + 32, key3] - mstore // [key3] - - 0x40 // [0x40, + 32, key3] - // [, 0x40, + 32, key3] - sha3 // [slot2, + 32, key3] - - // concat with the third key - swap1 // [ + 32, slot2, key3] put slot2 in memory - mstore // [key3] - - // put key3 in memory, before slot2 - // [, key3] - mstore // [] - - // Hash the data, generating the final slot3 - 0x40 // [0x40] - // [, 0x40] - sha3 // [slot3] -} - -/// @notice Load an element onto the stack from a key -#define macro LOAD_ELEMENT(mem_ptr) = takes(1) returns(1) { - // Input stack: [key] - GET_SLOT_FROM_KEY() // [slot] - sload // [value] -} - -/// @notice Load an element onto the stack from two keys -#define macro LOAD_ELEMENT_FROM_KEYS(mem_ptr) = takes(2) returns(1) { - // Input stack: [key1, key2] - GET_SLOT_FROM_KEYS() // [slot] - sload // [value] -} - -/// @notice Load an element onto the stack from a slot and two keys -#define macro LOAD_ELEMENT_FROM_KEYS_2D(mem_ptr) = takes(3) returns(1) { - // Input stack: [slot, key1, key2] - GET_SLOT_FROM_KEYS_2D() // [slot] - sload // [value] -} - -/// @notice Load an element onto the stack from a slot and three keys -#define macro LOAD_ELEMENT_FROM_KEYS_3D(mem_ptr) = takes(4) returns(1) { - // Input stack: [slot, key1, key2, key3] - GET_SLOT_FROM_KEYS_3D() // [slot] - sload // [value] -} - -/// @notice Store an element from a key -#define macro STORE_ELEMENT(mem_ptr) = takes(2) returns(0) { - // Input stack: [key, value] - GET_SLOT_FROM_KEY() // [slot, value] - sstore // [] -} - -/// @notice Store an element from two keys -#define macro STORE_ELEMENT_FROM_KEYS(mem_ptr) = takes(3) returns (0) { - // Input stack: [key1, key2, value] - GET_SLOT_FROM_KEYS() // [slot, value] - sstore // [] -} - -/// @notice Store an element from a slot and two keys -#define macro STORE_ELEMENT_FROM_KEYS_2D(mem_ptr) = takes(4) returns (0) { - // Input stack: [slot, key1, key2, value] - GET_SLOT_FROM_KEYS_2D() // [slot, value] - sstore // [] -} - -/// @notice Store an element from a slot and three keys -#define macro STORE_ELEMENT_FROM_KEYS_3D(mem_ptr) = takes(5) returns (0) { - // Input stack: [slot, key1, key2, key3, value] - GET_SLOT_FROM_KEYS_3D() // [slot, value] - sstore // [] -} \ No newline at end of file diff --git a/src/data-structures/__TEMP__lwkvhrrmofongwpxrjtworcwgnfqpxluBytes.huff b/src/data-structures/__TEMP__lwkvhrrmofongwpxrjtworcwgnfqpxluBytes.huff deleted file mode 100644 index fa739be2..00000000 --- a/src/data-structures/__TEMP__lwkvhrrmofongwpxrjtworcwgnfqpxluBytes.huff +++ /dev/null @@ -1,349 +0,0 @@ -#define macro SET_STOR(offset, value) = takes(2) returns(0) { - sstore // [] -} - -#define macro CONCAT_MEMORY_AND_SET1() = takes (0) returns (0) { - // remove func selector - pop - - 0x20 0x00 mstore - 0xbabe1babe1babe1babe1babe1babe1babe1babe1babe1babe1babe1babe1babe 0x20 mstore - - 0x20 0x40 mstore - 0xbabe2babe2babe2babe2babe2babe2babe2babe2babe2babe2babe2babe2babe 0x60 mstore - - 0x40 0x00 // [mem_ptr1, mem_ptr2] - CONCAT_MEMORY() // [pos] - - dup1 mload // [len, pos] - 0x00 SET_STOR() // [pos] - - dup1 0x20 add mload // [babe1, pos] - 0x20 SET_STOR() // [pos] - - 0x40 add mload // [babe2, pos] - 0x40 SET_STOR() // [pos] - - stop -} - -#define macro CONCAT_MEMORY_AND_SET2() = takes (0) returns (0) { - pop - - 0x20 0x00 mstore - 0xbabe1babe1babe1babe1babe1babe1babe1babe1babe1babe1babe1babe1babe 0x20 mstore - - 0x40 0x40 mstore - 0xbabe2babe2babe2babe2babe2babe2babe2babe2babe2babe2babe2babe2babe 0x60 mstore - 0xbabe2babe2babe2babe2babe2babe2babe2babe2babe2babe2babe2babe2babe 0x80 mstore - - 0x40 0x00 - CONCAT_MEMORY() - - dup1 mload - 0x00 SET_STOR() - - dup1 0x20 add mload - 0x20 SET_STOR() - - dup1 0x40 add mload - 0x40 SET_STOR() - - 0x60 add mload - 0x60 SET_STOR() - - stop -} - -#define macro CONCAT_MEMORY_AND_SET3() = takes (0) returns (0) { - pop - - 0x20 0x00 mstore - 0xbabe1babe1babe1babe1babe1babe1babe1babe1babe1babe1babe1babe1babe 0x20 mstore - - 0x00 0x40 mstore - - 0x40 0x00 - CONCAT_MEMORY() - - dup1 mload - 0x00 SET_STOR() - - dup1 0x20 add mload - 0x20 SET_STOR() - - stop -} - -#define macro CONCAT_MEMORY_AND_SET4() = takes (0) returns (0) { - pop - - 0x20 0x00 mstore - 0xbabe1babe1babe1babe1babe1babe1babe1babe1babe1babe1babe1babe1babe 0x20 mstore - - 0x05 0x40 mstore - __RIGHTPAD(0xbabe2babe2) 0x60 mstore - - 0x40 0x00 - CONCAT_MEMORY() - - dup1 mload - 0x00 SET_STOR() - - dup1 0x20 add mload - 0x20 SET_STOR() - - dup1 0x40 add mload - 0x40 SET_STOR() - - stop -} - -#define macro CONCAT_MEMORY_AND_SET5() = takes (0) returns (0) { - pop - - 0x0a 0x00 mstore - __RIGHTPAD(0xbabe1babe1babe1babe1) 0x20 mstore - - 0x05 0x40 mstore - __RIGHTPAD(0xbabe2babe2) 0x60 mstore - - 0x40 0x00 - CONCAT_MEMORY() - - dup1 mload - 0x00 SET_STOR() - - dup1 0x20 add mload - 0x20 SET_STOR() - - stop -} - -#define macro CONCAT_MEMORY_AND_SET6() = takes (0) returns (0) { - pop - - // don't need to be % 0x20 - 0x0a 0x05 mstore - __RIGHTPAD(0xbabe1babe1babe1babe1) 0x25 mstore - - 0x05 0x48 mstore - __RIGHTPAD(0xbabe2babe2) 0x68 mstore - - 0x48 0x05 - CONCAT_MEMORY() // [pos] - - dup1 mload // [len, pos] - 0x00 SET_STOR() // [pos] - - dup1 0x20 add mload // [babe1, pos] - 0x20 SET_STOR() // [pos] - - stop -} - -#define macro SLICE_MEMORY_AND_SET1() = takes (0) returns (0) { - pop - - 0x20 0x00 mstore - 0xbabe1babe1babe1babe1babe1babe1babe1babe1babe1babe1babe1babe1babe 0x20 mstore - - 0x10 0x00 0x00 // [mem_ptr, start, length] - SLICE_MEMORY() // [slice_ptr] - - dup1 mload - 0x00 SET_STOR() - - dup1 0x20 add mload - 0x20 SET_STOR() - - stop -} - -#define macro SLICE_MEMORY_AND_SET2() = takes (0) returns (0) { - pop - - 0x40 0x00 mstore - 0xbabe1babe1babe1babe1babe1babe1babe1babe1babe1babe1babe1babe1babe 0x20 mstore - 0xbabe2babe2babe2babe2babe2babe2babe2babe2babe2babe2babe2babe2babe 0x40 mstore - - 0x24 0x02 0x00 - SLICE_MEMORY() - - dup1 mload - 0x00 SET_STOR() - - dup1 0x20 add mload - 0x20 SET_STOR() - - dup1 0x40 add mload - 0x40 SET_STOR() - - stop -} - -#define macro SLICE_MEMORY_AND_SET3() = takes (0) returns (0) { - pop - - 0x40 0x07 mstore - 0xbabe1babe1babe1babe1babe1babe1babe1babe1babe1babe1babe1babe1babe 0x27 mstore - __RIGHTPAD(0xbabe2bab) 0x47 mstore - - 0x04 0x20 0x07 - SLICE_MEMORY() - - dup1 mload - 0x00 SET_STOR() - - dup1 0x20 add mload - 0x20 SET_STOR() - - stop -} - -#define macro MAIN() = takes (0) returns (0) { - 0x00 calldataload 0xE0 shr - dup1 __FUNC_SIG("concatMemoryAndSet1()") eq concatMemoryAndSet1 jumpi - dup1 __FUNC_SIG("concatMemoryAndSet2()") eq concatMemoryAndSet2 jumpi - dup1 __FUNC_SIG("concatMemoryAndSet3()") eq concatMemoryAndSet3 jumpi - dup1 __FUNC_SIG("concatMemoryAndSet4()") eq concatMemoryAndSet4 jumpi - dup1 __FUNC_SIG("concatMemoryAndSet5()") eq concatMemoryAndSet5 jumpi - dup1 __FUNC_SIG("concatMemoryAndSet6()") eq concatMemoryAndSet6 jumpi - dup1 __FUNC_SIG("sliceMemoryAndSet1()") eq sliceMemoryAndSet1 jumpi - dup1 __FUNC_SIG("sliceMemoryAndSet2()") eq sliceMemoryAndSet2 jumpi - dup1 __FUNC_SIG("sliceMemoryAndSet3()") eq sliceMemoryAndSet3 jumpi - - 0x00 0x00 revert - - concatMemoryAndSet1: - CONCAT_MEMORY_AND_SET1() - concatMemoryAndSet2: - CONCAT_MEMORY_AND_SET2() - concatMemoryAndSet3: - CONCAT_MEMORY_AND_SET3() - concatMemoryAndSet4: - CONCAT_MEMORY_AND_SET4() - concatMemoryAndSet5: - CONCAT_MEMORY_AND_SET5() - concatMemoryAndSet6: - CONCAT_MEMORY_AND_SET6() - sliceMemoryAndSet1: - SLICE_MEMORY_AND_SET1() - sliceMemoryAndSet2: - SLICE_MEMORY_AND_SET2() - sliceMemoryAndSet3: - SLICE_MEMORY_AND_SET3() -} - - -/// @title Bytes -/// @notice SPDX-License-Identifier: MIT -/// @author Franfran -/// @notice Low-level operations on bytes -/// @notice Adapted from BytesLib (https://github.com/GNSPS/solidity-bytes-utils/blob/master/contracts/BytesLib.sol) - -/// @notice Concatenate two bytes arrays -/// @notice Takes in two pointers of the bytes to concatenate that must be sorted -/// @return Pointer of the new appended concatenated bytes array in the memory -/// @dev Warning! This assumes that the pointer in the memory of the second bytes chunk is after mem_ptr1 + 0x20 -#define macro CONCAT_MEMORY() = takes(2) returns(1) { - // input stack // [mem_ptr1, mem_ptr2] - - // setup stack and memory for the next iterations - dup2 mload swap1 // [mem_ptr1, len2, mem_ptr2] - msize swap1 // [mem_ptr1, free_loc_pos, len2, mem_ptr2] - dup1 mload dup4 // [len2, len1, mem_ptr1, free_loc_pos, len2, mem_ptr2] - dup2 add msize mstore // [len1, mem_ptr1, free_loc_pos, len2, mem_ptr2] - - swap1 0x20 add // [index(i), len1, free_loc_pos, len2, mem_ptr2] - msize // [index(j), index(i), len1, free_loc_pos, len2, mem_ptr2] - swap2 0x00 // [is_sec_loop, len1, index(i), index(j), free_loc_pos, len2, mem_ptr2] - - // i is the index where we get (mload) the array element and j is the index where we store (mstore) the array at j - loop: // [is_sec_loop, len_left, index(i), index(j), free_loc_pos, len2, mem_ptr2] - dup2 iszero empty_slot jumpi // [is_sec_loop, len_left, index(i), index(j), free_loc_pos, len2, mem_ptr2] - - dup3 mload // [word, is_sec_loop, len_left, index(i), index(j), free_loc_pos, len2, mem_ptr2] - dup3 0x20 gt iszero // [is_full_slot, word, is_sec_loop, len_left, index(i), index(j), free_loc_pos, len2, mem_ptr2] - full_slot jumpi // [word, is_sec_loop, len_left, index(i), index(j), free_loc_pos, len2, mem_ptr2] - - // else it's not a full slot, we're hitting an end. Then clean memory slot and update j with a partial length - dup3 0x20 sub // [pad_len, word, is_sec_loop, len_left, index(i), index(j), free_loc_pos, len2, mem_ptr2] - 0x08 mul swap1 dup2 // [shift, word, shift, is_sec_loop, len_left, index(i), index(j), free_loc_pos, len2, mem_ptr2] - shr // [left_padded_word, shift, is_sec_loop, len_left, index(i), index(j), free_loc_pos, len2, mem_ptr2] - swap1 shl // [clean_word, is_sec_loop, len_left, index(i), index(j), free_loc_pos, len2, mem_ptr2] - dup5 mstore // [is_sec_loop, len_left, index(i), index(j), free_loc_pos, len2, mem_ptr2] - swap3 add swap2 // [is_sec_loop, index(i), index(j + 1), free_loc_pos, len2, mem_ptr2] - - // here we check if current loop is for the 2nd array - swap1 pop // [is_sec_loop, index(j + 1), free_loc_pos, len2, mem_ptr2] - iszero bridge jumpi // [index(j + 1), free_loc_pos, len2, mem_ptr2] - pop break jump // [free_loc_pos, len2, mem_ptr2] - - empty_slot: // [is_sec_loop, len_left, index(i), index(j), free_loc_pos, len2, mem_ptr2] - swap2 pop pop // [is_sec_loop, index(j), free_loc_pos, len2, mem_ptr2] - iszero bridge jumpi // [index(j), free_loc_pos, len2, mem_ptr2] - pop break jump // [free_loc_pos, len2, mem_ptr2] - - bridge: // [index(j), free_loc_pos, len2, mem_ptr2] - dup4 0x20 add // [index(i), index(j), free_loc_pos, len2, mem_ptr2] - dup5 // [len2, index(i), index(j), free_loc_pos, len2, mem_ptr2] - 0x01 // [is_sec_loop, len2, index(i), index(j), free_loc_pos, len2, mem_ptr2] - loop jump - - full_slot: // [word, is_sec_loop, len_left, index(i), index(j), free_loc_pos, len2, mem_ptr2] - dup5 mstore // [is_sec_loop, len_left, index(i), index(j), free_loc_pos, len2, mem_ptr2] - swap1 0x20 swap1 sub // [len_left - 0x20, is_sec_loop, index(i), index(j), free_loc_pos, len2, mem_ptr2] - swap2 0x20 add // [index(i + 1), is_sec_loop, len_left - 0x20, index(j), free_loc_pos, len2, mem_ptr2] - swap3 0x20 add // [index(j + 1), is_sec_loop, len_left - 0x20, index(i + 1), free_loc_pos, len2, mem_ptr2] - swap3 swap2 swap1 // [is_sec_loop, len_left - 0x20, index(i + 1), index(j + 1), free_loc_pos, len2, mem_ptr2] - loop jump - - break: // [free_loc_pos, len2, mem_ptr2] - swap2 pop pop // [free_loc_pos] -} - -/// @param Pointer in memory of the start of the bytes array -/// @param Start position of the slice relative to the array -/// @param Length of the output slice -/// @return Pointer of the new appended concatenated bytes array in the memory -/// @dev Warning! This assumes that the length of the output slice is less or equal the length of the bytes array (bytes.len < slice.len) -/// @dev Warning! This assumes that the start of the bytes array is not out of bounds (start < len + mem_ptr) -#define macro SLICE_MEMORY() = takes(3) returns(1) { - // input stack // [mem_ptr, start, length] - - msize dup4 msize mstore // [free_loc_pos, mem_ptr, start, length] - msize swap4 // [length, free_loc_pos, mem_ptr, start, index(j)] - // index(i) = mem_ptr + start + 0x20 - swap1 swap3 // [start, length, mem_ptr, free_loc_pos, index(j)] - swap1 swap2 // [mem_ptr, start, length, free_loc_pos, index(j)] - 0x20 add add // [index(i), length, free_loc_pos, index(j)] - - // we load our slice chunk at i and store it in a free memory location at j - loop: // [index(i), length_left, free_loc_pos, index(j)] - dup1 mload // [slice_chunk, index(i), length_left, free_loc_pos, index(j)] - - // if current is not full slot, then load the last bytes and break - 0x20 dup4 lt // [is_not_full_slot, slice_chunk, index(i), length_left, free_loc_pos, index(j)] - break jumpi // [slice_chunk, index(i), length_left, free_loc_pos, index(j)] - - dup5 mstore // [index(i), length_left, free_loc_pos, index(j)] - - 0x20 add swap3 // [free_loc, length_left, free_loc_pos, index(i+1)] - 0x20 add swap3 // [index(i+1), length_left, free_loc_pos, free_loc + 1] - swap1 0x20 // [0x20, length_left, index(i+1), free_loc_pos, free_loc + 1] - swap1 sub // [length_left - 1, index(i+1), free_loc_pos, free_loc + 1] - swap1 // [index(i+1), length_left - 1, free_loc_pos, free_loc + 1] - - loop jump - - break: // [slice_chunk, index(i), length, free_loc_pos, index(j)] - // store the remaining length - dup3 0x20 sub // [zero_length, slice_chunk, index(i), length, free_loc_pos, index(j)] - 0x08 mul swap1 dup2 // [shift, slice_chunk, shift, index(i), length, free_loc_pos, index(j)] - shr // [left_pad_slice, shift, index(i), length, free_loc_pos, index(j)] - swap1 shl // [slice_chunk, index(i), length, free_loc_pos, index(j)] - dup5 mstore // [index(i), length, free_loc_pos, index(j)] - - pop pop swap1 pop // [free_loc_pos] -} diff --git a/src/data-structures/__TEMP__swmivzahxlhrjuiphjztstbcaymhckevArrays.huff b/src/data-structures/__TEMP__swmivzahxlhrjuiphjztstbcaymhckevArrays.huff deleted file mode 100644 index d63bae3b..00000000 --- a/src/data-structures/__TEMP__swmivzahxlhrjuiphjztstbcaymhckevArrays.huff +++ /dev/null @@ -1,121 +0,0 @@ -// Sets an array from calldata. -// sig: 0x226ce6b7 -#define function setArrayFromCalldata(uint256[]) view returns () - -// Returns an array. -// sig: 0xde9ee75c -#define function loadArray() view returns (uint256[] memory) - -#define constant LOCATION = FREE_STORAGE_POINTER() - -#define macro SET_FROM_CALLDATA() = takes(0) returns(0) { - [LOCATION] 0x04 - SET_ARRAY_FROM_CALLDATA() - stop -} - - -// Store the value for the given key. -#define macro RETURN() = takes(0) returns(0) { - [LOCATION] - RETURN_ARRAY(0x80) -} - -/* Main Macro - The contract entrypoint */ -#define macro MAIN() = takes(0) returns (0) { - // Identify which function is being called using the 4 byte function signature - 0x00 calldataload 0xE0 shr - dup1 __FUNC_SIG(setArrayFromCalldata) eq set_from_calldata jumpi - dup1 __FUNC_SIG(loadArray) eq load jumpi - - // Revert if otherwise - 0x00 0x00 revert - - set_from_calldata: - SET_FROM_CALLDATA() - load: - RETURN() -} - - -/// @title Arrays -/// @notice SPDX-License-Identifier: MIT -/// @author exp-table -/// @notice Array utility library for Solidity contracts - -/// @notice Sets an array in storage from calldata. -/// Note that since no assumptions is made regarding the context in which -/// this function is called, the position of the encoded array in the calldata -/// has to be specified. -#define macro SET_ARRAY_FROM_CALLDATA() = takes(2) returns (0) { - // Input stack: [calldata_start, slot] - // skip size of one individual element - 0x20 add // [calldata_start+0x20, slot] - dup1 0x20 add swap1 // [calldata_start+0x20, calldata_start+0x40, slot] - // load length - calldataload // [length, calldata_offset, slot] - // store length at slot - dup1 dup4 // [slot, length, length, calldata_offset, slot] - sstore // [length, calldata_offset, slot] - - // store slot in memory scratch space and compute hash - dup3 0x00 mstore // [length, calldata_offset, slot] - 0x20 0x00 sha3 // [sha3(slot), length, ,calldata_offset slot] - - // loop and store every element in slot sha3(slot)+n - 0x00 // [index(0), sha3(slot), length, calldata_offset, slot] - start jump - continue: - // if index == length -> it's over - eq end jumpi // [index(i), sha3(slot), length, calldata_offset, slot] - start: - // load from calldata - dup1 0x20 mul dup5 add calldataload // [array(i), index(i), sha3(slot), length, calldata_offset, slot] - // store at slot sha3(slot)+index - dup3 dup3 add sstore // [index(i), sha3(slot), length, calldata_offset, slot] - // inc index - 0x01 add // [index(i+1), sha3(slot), length, calldata_offset, slot] - dup3 dup2 // [index(i+1), length, index(i+1), sha3(slot), length, calldata_offset, slot] - continue jump - - end: -} - -/// @notice Returns an array in memory specified at {mem_ptr} -#define macro RETURN_ARRAY(mem_ptr) = takes(1) returns (0) { - // Input stack: [slot] - - // store the size of each element in memory - 0x20 mstore // [slot] - // [mem_ptr, slot] - // load length from storage - dup2 sload dup1 // [length, length, curr_mem_ptr, slot] - // store length in memory - swap2 0x20 add // [curr_mem_ptr+0x20, length, length, slot] - swap1 dup2 mstore // [curr_mem_ptr, length, slot] - - // store slot in memory scratch space and compute hash - swap2 0x00 mstore // [length, curr_mem_ptr] - 0x20 0x00 sha3 swap2 // [curr_mem_ptr, length, sha3(slot)] - - // loop and load every element in slot sha3(slot)+n - 0x00 start jump // [index(0), curr_mem_ptr, length, sha3(slot)] - continue: - // if index == length -> it's over - eq end jumpi // [index(i), curr_mem_ptr, length, sha3(slot)] - start: - // load from storage ; add index to sha3(slot) - dup1 dup5 add sload // [array(i), index(i), curr_mem_ptr, length, sha3(slot)] - // store in memory - swap1 swap2 0x20 add // [curr_mem_ptr+0x20, array(i), index(i), length, sha3(slot)] - dup1 swap2 swap1 mstore // [curr_mem_ptr+0x20, index(i), length, sha3(slot)] - // update index - swap1 0x01 add // [index(i+1), curr_mem_ptr, length, sha3(slot)] - dup1 dup4 - continue jump - - end: - // size of data to return = size of individual element + array length + encoded elements - swap2 0x02 add 0x05 shl // [size, curr_mem_ptr, index(i), sha3(slot)] - return -} \ No newline at end of file diff --git a/src/data-structures/__TEMP__wvnaxkgsgqemkcqoqqvognrxtldwtppxBytes.huff b/src/data-structures/__TEMP__wvnaxkgsgqemkcqoqqvognrxtldwtppxBytes.huff deleted file mode 100644 index fa739be2..00000000 --- a/src/data-structures/__TEMP__wvnaxkgsgqemkcqoqqvognrxtldwtppxBytes.huff +++ /dev/null @@ -1,349 +0,0 @@ -#define macro SET_STOR(offset, value) = takes(2) returns(0) { - sstore // [] -} - -#define macro CONCAT_MEMORY_AND_SET1() = takes (0) returns (0) { - // remove func selector - pop - - 0x20 0x00 mstore - 0xbabe1babe1babe1babe1babe1babe1babe1babe1babe1babe1babe1babe1babe 0x20 mstore - - 0x20 0x40 mstore - 0xbabe2babe2babe2babe2babe2babe2babe2babe2babe2babe2babe2babe2babe 0x60 mstore - - 0x40 0x00 // [mem_ptr1, mem_ptr2] - CONCAT_MEMORY() // [pos] - - dup1 mload // [len, pos] - 0x00 SET_STOR() // [pos] - - dup1 0x20 add mload // [babe1, pos] - 0x20 SET_STOR() // [pos] - - 0x40 add mload // [babe2, pos] - 0x40 SET_STOR() // [pos] - - stop -} - -#define macro CONCAT_MEMORY_AND_SET2() = takes (0) returns (0) { - pop - - 0x20 0x00 mstore - 0xbabe1babe1babe1babe1babe1babe1babe1babe1babe1babe1babe1babe1babe 0x20 mstore - - 0x40 0x40 mstore - 0xbabe2babe2babe2babe2babe2babe2babe2babe2babe2babe2babe2babe2babe 0x60 mstore - 0xbabe2babe2babe2babe2babe2babe2babe2babe2babe2babe2babe2babe2babe 0x80 mstore - - 0x40 0x00 - CONCAT_MEMORY() - - dup1 mload - 0x00 SET_STOR() - - dup1 0x20 add mload - 0x20 SET_STOR() - - dup1 0x40 add mload - 0x40 SET_STOR() - - 0x60 add mload - 0x60 SET_STOR() - - stop -} - -#define macro CONCAT_MEMORY_AND_SET3() = takes (0) returns (0) { - pop - - 0x20 0x00 mstore - 0xbabe1babe1babe1babe1babe1babe1babe1babe1babe1babe1babe1babe1babe 0x20 mstore - - 0x00 0x40 mstore - - 0x40 0x00 - CONCAT_MEMORY() - - dup1 mload - 0x00 SET_STOR() - - dup1 0x20 add mload - 0x20 SET_STOR() - - stop -} - -#define macro CONCAT_MEMORY_AND_SET4() = takes (0) returns (0) { - pop - - 0x20 0x00 mstore - 0xbabe1babe1babe1babe1babe1babe1babe1babe1babe1babe1babe1babe1babe 0x20 mstore - - 0x05 0x40 mstore - __RIGHTPAD(0xbabe2babe2) 0x60 mstore - - 0x40 0x00 - CONCAT_MEMORY() - - dup1 mload - 0x00 SET_STOR() - - dup1 0x20 add mload - 0x20 SET_STOR() - - dup1 0x40 add mload - 0x40 SET_STOR() - - stop -} - -#define macro CONCAT_MEMORY_AND_SET5() = takes (0) returns (0) { - pop - - 0x0a 0x00 mstore - __RIGHTPAD(0xbabe1babe1babe1babe1) 0x20 mstore - - 0x05 0x40 mstore - __RIGHTPAD(0xbabe2babe2) 0x60 mstore - - 0x40 0x00 - CONCAT_MEMORY() - - dup1 mload - 0x00 SET_STOR() - - dup1 0x20 add mload - 0x20 SET_STOR() - - stop -} - -#define macro CONCAT_MEMORY_AND_SET6() = takes (0) returns (0) { - pop - - // don't need to be % 0x20 - 0x0a 0x05 mstore - __RIGHTPAD(0xbabe1babe1babe1babe1) 0x25 mstore - - 0x05 0x48 mstore - __RIGHTPAD(0xbabe2babe2) 0x68 mstore - - 0x48 0x05 - CONCAT_MEMORY() // [pos] - - dup1 mload // [len, pos] - 0x00 SET_STOR() // [pos] - - dup1 0x20 add mload // [babe1, pos] - 0x20 SET_STOR() // [pos] - - stop -} - -#define macro SLICE_MEMORY_AND_SET1() = takes (0) returns (0) { - pop - - 0x20 0x00 mstore - 0xbabe1babe1babe1babe1babe1babe1babe1babe1babe1babe1babe1babe1babe 0x20 mstore - - 0x10 0x00 0x00 // [mem_ptr, start, length] - SLICE_MEMORY() // [slice_ptr] - - dup1 mload - 0x00 SET_STOR() - - dup1 0x20 add mload - 0x20 SET_STOR() - - stop -} - -#define macro SLICE_MEMORY_AND_SET2() = takes (0) returns (0) { - pop - - 0x40 0x00 mstore - 0xbabe1babe1babe1babe1babe1babe1babe1babe1babe1babe1babe1babe1babe 0x20 mstore - 0xbabe2babe2babe2babe2babe2babe2babe2babe2babe2babe2babe2babe2babe 0x40 mstore - - 0x24 0x02 0x00 - SLICE_MEMORY() - - dup1 mload - 0x00 SET_STOR() - - dup1 0x20 add mload - 0x20 SET_STOR() - - dup1 0x40 add mload - 0x40 SET_STOR() - - stop -} - -#define macro SLICE_MEMORY_AND_SET3() = takes (0) returns (0) { - pop - - 0x40 0x07 mstore - 0xbabe1babe1babe1babe1babe1babe1babe1babe1babe1babe1babe1babe1babe 0x27 mstore - __RIGHTPAD(0xbabe2bab) 0x47 mstore - - 0x04 0x20 0x07 - SLICE_MEMORY() - - dup1 mload - 0x00 SET_STOR() - - dup1 0x20 add mload - 0x20 SET_STOR() - - stop -} - -#define macro MAIN() = takes (0) returns (0) { - 0x00 calldataload 0xE0 shr - dup1 __FUNC_SIG("concatMemoryAndSet1()") eq concatMemoryAndSet1 jumpi - dup1 __FUNC_SIG("concatMemoryAndSet2()") eq concatMemoryAndSet2 jumpi - dup1 __FUNC_SIG("concatMemoryAndSet3()") eq concatMemoryAndSet3 jumpi - dup1 __FUNC_SIG("concatMemoryAndSet4()") eq concatMemoryAndSet4 jumpi - dup1 __FUNC_SIG("concatMemoryAndSet5()") eq concatMemoryAndSet5 jumpi - dup1 __FUNC_SIG("concatMemoryAndSet6()") eq concatMemoryAndSet6 jumpi - dup1 __FUNC_SIG("sliceMemoryAndSet1()") eq sliceMemoryAndSet1 jumpi - dup1 __FUNC_SIG("sliceMemoryAndSet2()") eq sliceMemoryAndSet2 jumpi - dup1 __FUNC_SIG("sliceMemoryAndSet3()") eq sliceMemoryAndSet3 jumpi - - 0x00 0x00 revert - - concatMemoryAndSet1: - CONCAT_MEMORY_AND_SET1() - concatMemoryAndSet2: - CONCAT_MEMORY_AND_SET2() - concatMemoryAndSet3: - CONCAT_MEMORY_AND_SET3() - concatMemoryAndSet4: - CONCAT_MEMORY_AND_SET4() - concatMemoryAndSet5: - CONCAT_MEMORY_AND_SET5() - concatMemoryAndSet6: - CONCAT_MEMORY_AND_SET6() - sliceMemoryAndSet1: - SLICE_MEMORY_AND_SET1() - sliceMemoryAndSet2: - SLICE_MEMORY_AND_SET2() - sliceMemoryAndSet3: - SLICE_MEMORY_AND_SET3() -} - - -/// @title Bytes -/// @notice SPDX-License-Identifier: MIT -/// @author Franfran -/// @notice Low-level operations on bytes -/// @notice Adapted from BytesLib (https://github.com/GNSPS/solidity-bytes-utils/blob/master/contracts/BytesLib.sol) - -/// @notice Concatenate two bytes arrays -/// @notice Takes in two pointers of the bytes to concatenate that must be sorted -/// @return Pointer of the new appended concatenated bytes array in the memory -/// @dev Warning! This assumes that the pointer in the memory of the second bytes chunk is after mem_ptr1 + 0x20 -#define macro CONCAT_MEMORY() = takes(2) returns(1) { - // input stack // [mem_ptr1, mem_ptr2] - - // setup stack and memory for the next iterations - dup2 mload swap1 // [mem_ptr1, len2, mem_ptr2] - msize swap1 // [mem_ptr1, free_loc_pos, len2, mem_ptr2] - dup1 mload dup4 // [len2, len1, mem_ptr1, free_loc_pos, len2, mem_ptr2] - dup2 add msize mstore // [len1, mem_ptr1, free_loc_pos, len2, mem_ptr2] - - swap1 0x20 add // [index(i), len1, free_loc_pos, len2, mem_ptr2] - msize // [index(j), index(i), len1, free_loc_pos, len2, mem_ptr2] - swap2 0x00 // [is_sec_loop, len1, index(i), index(j), free_loc_pos, len2, mem_ptr2] - - // i is the index where we get (mload) the array element and j is the index where we store (mstore) the array at j - loop: // [is_sec_loop, len_left, index(i), index(j), free_loc_pos, len2, mem_ptr2] - dup2 iszero empty_slot jumpi // [is_sec_loop, len_left, index(i), index(j), free_loc_pos, len2, mem_ptr2] - - dup3 mload // [word, is_sec_loop, len_left, index(i), index(j), free_loc_pos, len2, mem_ptr2] - dup3 0x20 gt iszero // [is_full_slot, word, is_sec_loop, len_left, index(i), index(j), free_loc_pos, len2, mem_ptr2] - full_slot jumpi // [word, is_sec_loop, len_left, index(i), index(j), free_loc_pos, len2, mem_ptr2] - - // else it's not a full slot, we're hitting an end. Then clean memory slot and update j with a partial length - dup3 0x20 sub // [pad_len, word, is_sec_loop, len_left, index(i), index(j), free_loc_pos, len2, mem_ptr2] - 0x08 mul swap1 dup2 // [shift, word, shift, is_sec_loop, len_left, index(i), index(j), free_loc_pos, len2, mem_ptr2] - shr // [left_padded_word, shift, is_sec_loop, len_left, index(i), index(j), free_loc_pos, len2, mem_ptr2] - swap1 shl // [clean_word, is_sec_loop, len_left, index(i), index(j), free_loc_pos, len2, mem_ptr2] - dup5 mstore // [is_sec_loop, len_left, index(i), index(j), free_loc_pos, len2, mem_ptr2] - swap3 add swap2 // [is_sec_loop, index(i), index(j + 1), free_loc_pos, len2, mem_ptr2] - - // here we check if current loop is for the 2nd array - swap1 pop // [is_sec_loop, index(j + 1), free_loc_pos, len2, mem_ptr2] - iszero bridge jumpi // [index(j + 1), free_loc_pos, len2, mem_ptr2] - pop break jump // [free_loc_pos, len2, mem_ptr2] - - empty_slot: // [is_sec_loop, len_left, index(i), index(j), free_loc_pos, len2, mem_ptr2] - swap2 pop pop // [is_sec_loop, index(j), free_loc_pos, len2, mem_ptr2] - iszero bridge jumpi // [index(j), free_loc_pos, len2, mem_ptr2] - pop break jump // [free_loc_pos, len2, mem_ptr2] - - bridge: // [index(j), free_loc_pos, len2, mem_ptr2] - dup4 0x20 add // [index(i), index(j), free_loc_pos, len2, mem_ptr2] - dup5 // [len2, index(i), index(j), free_loc_pos, len2, mem_ptr2] - 0x01 // [is_sec_loop, len2, index(i), index(j), free_loc_pos, len2, mem_ptr2] - loop jump - - full_slot: // [word, is_sec_loop, len_left, index(i), index(j), free_loc_pos, len2, mem_ptr2] - dup5 mstore // [is_sec_loop, len_left, index(i), index(j), free_loc_pos, len2, mem_ptr2] - swap1 0x20 swap1 sub // [len_left - 0x20, is_sec_loop, index(i), index(j), free_loc_pos, len2, mem_ptr2] - swap2 0x20 add // [index(i + 1), is_sec_loop, len_left - 0x20, index(j), free_loc_pos, len2, mem_ptr2] - swap3 0x20 add // [index(j + 1), is_sec_loop, len_left - 0x20, index(i + 1), free_loc_pos, len2, mem_ptr2] - swap3 swap2 swap1 // [is_sec_loop, len_left - 0x20, index(i + 1), index(j + 1), free_loc_pos, len2, mem_ptr2] - loop jump - - break: // [free_loc_pos, len2, mem_ptr2] - swap2 pop pop // [free_loc_pos] -} - -/// @param Pointer in memory of the start of the bytes array -/// @param Start position of the slice relative to the array -/// @param Length of the output slice -/// @return Pointer of the new appended concatenated bytes array in the memory -/// @dev Warning! This assumes that the length of the output slice is less or equal the length of the bytes array (bytes.len < slice.len) -/// @dev Warning! This assumes that the start of the bytes array is not out of bounds (start < len + mem_ptr) -#define macro SLICE_MEMORY() = takes(3) returns(1) { - // input stack // [mem_ptr, start, length] - - msize dup4 msize mstore // [free_loc_pos, mem_ptr, start, length] - msize swap4 // [length, free_loc_pos, mem_ptr, start, index(j)] - // index(i) = mem_ptr + start + 0x20 - swap1 swap3 // [start, length, mem_ptr, free_loc_pos, index(j)] - swap1 swap2 // [mem_ptr, start, length, free_loc_pos, index(j)] - 0x20 add add // [index(i), length, free_loc_pos, index(j)] - - // we load our slice chunk at i and store it in a free memory location at j - loop: // [index(i), length_left, free_loc_pos, index(j)] - dup1 mload // [slice_chunk, index(i), length_left, free_loc_pos, index(j)] - - // if current is not full slot, then load the last bytes and break - 0x20 dup4 lt // [is_not_full_slot, slice_chunk, index(i), length_left, free_loc_pos, index(j)] - break jumpi // [slice_chunk, index(i), length_left, free_loc_pos, index(j)] - - dup5 mstore // [index(i), length_left, free_loc_pos, index(j)] - - 0x20 add swap3 // [free_loc, length_left, free_loc_pos, index(i+1)] - 0x20 add swap3 // [index(i+1), length_left, free_loc_pos, free_loc + 1] - swap1 0x20 // [0x20, length_left, index(i+1), free_loc_pos, free_loc + 1] - swap1 sub // [length_left - 1, index(i+1), free_loc_pos, free_loc + 1] - swap1 // [index(i+1), length_left - 1, free_loc_pos, free_loc + 1] - - loop jump - - break: // [slice_chunk, index(i), length, free_loc_pos, index(j)] - // store the remaining length - dup3 0x20 sub // [zero_length, slice_chunk, index(i), length, free_loc_pos, index(j)] - 0x08 mul swap1 dup2 // [shift, slice_chunk, shift, index(i), length, free_loc_pos, index(j)] - shr // [left_pad_slice, shift, index(i), length, free_loc_pos, index(j)] - swap1 shl // [slice_chunk, index(i), length, free_loc_pos, index(j)] - dup5 mstore // [index(i), length, free_loc_pos, index(j)] - - pop pop swap1 pop // [free_loc_pos] -} diff --git a/src/math/__TEMP__agffsybhummgrdmhvrzqoxrnkhupycfeMath.huff b/src/math/__TEMP__agffsybhummgrdmhvrzqoxrnkhupycfeMath.huff deleted file mode 100644 index 1c65a83e..00000000 --- a/src/math/__TEMP__agffsybhummgrdmhvrzqoxrnkhupycfeMath.huff +++ /dev/null @@ -1,319 +0,0 @@ - -#define macro SQRT_WRAPPER() = { - 0x04 calldataload - SQRT() - 0x00 mstore - 0x20 0x00 return -} - -#define macro MAX_WRAPPER() = { - 0x04 calldataload - 0x24 calldataload - MAX() - 0x00 mstore - 0x20 0x00 return -} - -#define macro MIN_WRAPPER() = { - 0x04 calldataload - 0x24 calldataload - MIN() - 0x00 mstore - 0x20 0x00 return -} - -#define macro AVG_WRAPPER() = { - 0x04 calldataload - 0x24 calldataload - AVG() - 0x00 mstore - 0x20 0x00 return -} - -#define macro CEIL_DIV_WRAPPER() = { - 0x24 calldataload - 0x04 calldataload - CEIL_DIV() - 0x00 mstore - 0x20 0x00 return -} - -#define macro MAIN() = { - 0x00 calldataload 0xE0 shr - dup1 __FUNC_SIG(sqrt) eq sqrt jumpi - dup1 __FUNC_SIG(max) eq max jumpi - dup1 __FUNC_SIG(min) eq min jumpi - dup1 __FUNC_SIG(average) eq average jumpi - dup1 __FUNC_SIG(ceilDiv) eq ceilDiv jumpi - - 0x00 0x00 revert - - sqrt: - SQRT_WRAPPER() - max: - MAX_WRAPPER() - min: - MIN_WRAPPER() - average: - AVG_WRAPPER() - ceilDiv: - CEIL_DIV_WRAPPER() -} - - -/// @title Math -/// @notice SPDX-License-Identifier: MIT -/// @author manas -/// @author kadenzipfel -/// @notice Math module over Solidity's arithmetic operations -/// @notice Adapted from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/math/Math.sol) - -#include "../utils/Errors.huff" - -// Interface -#define function sqrt(uint256) pure returns(uint256) -#define function max(uint256, uint256) pure returns(uint256) -#define function min(uint256, uint256) pure returns(uint256) -#define function average(uint256, uint256) pure returns(uint256) -#define function ceilDiv(uint256, uint256) pure returns(uint256) - -// Negative 1 in two's compliment -#define constant NEG1 = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff - -/// @notice Calculates the square root of a stack input -#define macro SQRT() = takes (1) returns (1) { - // input stack // [num] - // if num == 0 return 0 - dup1 // [number, number] - iszero // [is_zero, number] - is_zero jumpi - - // assign stack vars - dup1 // [x, num] - 0x01 // [result, x, num] - - // if (x >> 128 > 0) { - // x >>= 128; - // result <<= 64; - // } - dup2 // [x, result, x, num] - 0x80 shr // [x >> 128, result, x, num] - dup1 // [x >> 128, x >> 128, result, x, num] - iszero // [x >> 128 == 0, x >> 128, result, x, num] - sh_128_0 jumpi - swap1 0x40 shl // [result, x >> 128, x, num] - swap1 swap2 // [x, result, x >> 128, num] - sh_128_0: - pop - - // if (x >> 64 > 0) { - // x >>= 64; - // result <<= 32; - // } - dup2 // [x, result, x, num] - 0x40 shr // [x >> 64, result, x, num] - dup1 // [x >> 64, x >> 64, result, x, num] - iszero // [x >> 64 == 0, x >> 64, result, x, num] - sh_64_0 jumpi - swap1 0x20 shl // [result, x >> 64, x, num] - swap1 swap2 // [x, result, x >> 64, num] - sh_64_0: - pop - - // if (x >> 32 > 0) { - // x >>= 32; - // result <<= 16; - // } - dup2 // [x, result, x, num] - 0x20 shr // [x >> 32, result, x, num] - dup1 // [x >> 32, x >> 32, result, x, num] - iszero // [x >> 32 == 0, x >> 32, result, x, num] - sh_32_0 jumpi - swap1 0x10 shl // [result, x >> 32, x, num] - swap1 swap2 // [x, result, x >> 32, num] - sh_32_0: - pop - - // if (x >> 16 > 0) { - // x >>= 16; - // result <<= 8; - // } - dup2 // [x, result, x, num] - 0x10 shr // [x >> 16, result, x, num] - dup1 // [x >> 16, x >> 16, result, x, num] - iszero // [x >> 16 == 0, x >> 16, result, x, num] - sh_16_0 jumpi - swap1 0x08 shl // [result, x >> 16, x, num] - swap1 swap2 // [x, result, x >> 16, num] - sh_16_0: - pop - - // if (x >> 8 > 0) { - // x >>= 8; - // result <<= 4; - // } - dup2 // [x, result, x, num] - 0x08 shr // [x >> 8, result, x, num] - dup1 // [x >> 8, x >> 8, result, x, num] - iszero // [x >> 8 == 0, x >> 8, result, x, num] - sh_8_0 jumpi - swap1 0x04 shl // [result, x >> 8, x, num] - swap1 swap2 // [x, result, x >> 8, num] - sh_8_0: - pop - - // if (x >> 4 > 0) { - // x >>= 4; - // result <<= 2; - // } - dup2 // [x, result, x, num] - 0x04 shr // [x >> 4, result, x, num] - dup1 // [x >> 4, x >> 4, result, x, num] - iszero // [x >> 4 == 0, x >> 4, result, x, num] - sh_4_0 jumpi - swap1 0x02 shl // [result, x >> 4, x, num] - swap1 swap2 // [x, result, x >> 4, num] - sh_4_0: - pop - - // if (x >> 2 > 0) { - // x >>= 2; - // result <<= 1; - // } - dup2 // [x, result, x, num] - 0x02 shr // [x >> 2, result, x, num] - dup1 // [x >> 2, x >> 2, result, x, num] - iszero // [x >> 2 == 0, x >> 2, result, x, num] - sh_2_0 jumpi - swap1 0x01 shl // [result, x >> 2, x, num] - swap1 swap2 // [x, result, x >> 2, num] - sh_2_0: - pop - - // result = (result + num / result) >> 1; - dup1 // [result, result, x, num] - dup4 // [num, result, result, x, num] - div // [num / result, result x, num] - add // [result + num / result, x, num] - 0x01 shr // [result, x, num] - - // result = (result + num / result) >> 1; - dup1 // [result, result, x, num] - dup4 // [num, result, result, x, num] - div // [num / result, result, x, num] - add // [result + num / result, x, num] - 0x01 shr // [result, x, num] - - // result = (result + num / result) >> 1; - dup1 // [result, result, x, num] - dup4 // [num, result, result, x, num] - div // [num / result, result, x, num] - add // [result + num / result, x, num] - 0x01 shr // [result, x, num] - - // result = (result + num / result) >> 1; - dup1 // [result, result, x, num] - dup4 // [num, result, result, x, num] - div // [num / result, result, x, num] - add // [result + num / result, x, num] - 0x01 shr // [result, x, num] - - // result = (result + num / result) >> 1; - dup1 // [result, result, x, num] - dup4 // [num, result, result, x, num] - div // [num / result, result, x, num] - add // [result + num / result, x, num] - 0x01 shr // [result, x, num] - - // result = (result + num / result) >> 1; - dup1 // [result, result, x, num] - dup4 // [num, result, result, x, num] - div // [num / result, result, x, num] - add // [result + num / result, x, num] - 0x01 shr // [result, x, num] - - // result = (result + num / result) >> 1; - dup1 // [result, result, x, num] - dup4 // [num, result, result, x, num] - div // [num / result, result, x, num] - add // [result + num / result, x, num] - 0x01 shr // [result, x, num] - - // result = min(result, num / result) - dup1 // [result, result, x, num] - swap3 // [num, result, x, result] - div // [num / result, x, result] - swap2 swap1 pop // [result, num / result] - MIN() - - is_zero: -} - -/// @notice Returns the maximum value of two values on the stack -#define macro MAX() = takes (2) returns (1) { - // input stack: // [num1, num2] - dup2 // [num2, num1, num2] - dup2 // [num1, num2, num1, num2] - lt // [is_less_than, num1, num2] - - less_than jumpi - swap1 // [num1, num2] - - less_than: - pop // [max(num2, num1)] -} - -/// @notice Returns the ceiling of the division of two values on the stack -#define macro CEIL_DIV() = takes (2) returns (1) { - // input stack: // [num1, num2] - dup1 iszero // [is_zero, num1, num2] - if_zero jumpi - - dup2 iszero // [is_zero, num1, num2] - divide_by_zero jumpi - - 0x01 // [1, num1, num2] - swap1 // [num1, 1, num1] - sub // [num1 - 1, num2] - div 0x01 add // [((num1 - 1) / num2) + 1] - dest jump - - divide_by_zero: - [DIVIDE_BY_ZERO] PANIC() - - if_zero: - swap1 // [num2, num1] - pop // [num1] - - dest: -} - -/// @notice Returns the minimum value of two values on the stack -#define macro MIN() = takes (2) returns (1) { - // input stack: // [num1, num2] - dup2 dup2 gt // [is_greater_than, num1, num2] - - greater_than jumpi - swap1 // [num2, num1] - - greater_than: - pop // [min(num1, num2)] -} - -/// @notice Returns the average of two values on the stack -#define macro AVG() = takes (2) returns (1) { - // input stack: // [num1, num2] - dup2 dup2 and // [num1 & num2, num1, num2] - swap2 // [num2, num1, num1 & num2] - xor // [num2 ^ num1, num1 & num2] - 0x02 swap1 div // [num2 ^ num1 / 2, num1 & num2] - add // [sum] -} - -/// @notice Unsafely subtracts 1 from a uint256 using the 2's complement representation -#define macro UNSAFE_SUB() = takes (1) returns (1) { - // Input Stack: [x] - // Output Stack: [x - 1] - - [NEG1] add // [x - 1] -} \ No newline at end of file diff --git a/src/math/__TEMP__gtvxtadnkjdmxsyyimfngsleoolwhcqtSafeMath.huff b/src/math/__TEMP__gtvxtadnkjdmxsyyimfngsleoolwhcqtSafeMath.huff deleted file mode 100644 index 8ac2256c..00000000 --- a/src/math/__TEMP__gtvxtadnkjdmxsyyimfngsleoolwhcqtSafeMath.huff +++ /dev/null @@ -1,153 +0,0 @@ - -// Wrapper methods (for testing) -#define macro SAFE_ADD_WRAPPER() = takes (0) returns (0) { - 0x04 calldataload // [num1] - 0x24 calldataload // [num2, num1] - SAFE_ADD() // [result] - 0x00 mstore // [] - 0x20 0x00 return // [] -} - -#define macro SAFE_SUB_WRAPPER() = takes (0) returns (0) { - 0x04 calldataload // [num1] - 0x24 calldataload // [num2, num1] - swap1 // [num1, num2] - SAFE_SUB() // [result] - 0x00 mstore // [] - 0x20 0x00 return // [] -} - -#define macro SAFE_MUL_WRAPPER() = takes (0) returns (0) { - 0x04 calldataload // [num1] - 0x24 calldataload // [num2, num1] - SAFE_MUL() // [result] - 0x00 mstore // [] - 0x20 0x00 return // [] -} - -#define macro SAFE_DIV_WRAPPER() = takes (0) returns (0) { - 0x04 calldataload // [num1] - 0x24 calldataload // [num2, num1] - swap1 // [num1, num2] - SAFE_DIV() // [result] - 0x00 mstore // [] - 0x20 0x00 return // [] -} - -#define macro SAFE_MOD_WRAPPER() = takes (0) returns (0) { - 0x04 calldataload // [num1] - 0x24 calldataload // [num2, num1] - swap1 // [num1, num2] - SAFE_MOD() // [result] - 0x00 mstore // [] - 0x20 0x00 return // [] -} - -// Main -#define macro MAIN() = takes (0) returns (0) { - 0x00 calldataload 0xE0 shr - dup1 __FUNC_SIG(safeAdd) eq safe_add jumpi - dup1 __FUNC_SIG(safeSub) eq safe_sub jumpi - dup1 __FUNC_SIG(safeMul) eq safe_mul jumpi - dup1 __FUNC_SIG(safeDiv) eq safe_div jumpi - dup1 __FUNC_SIG(safeMod) eq safe_mod jumpi - - 0x00 0x00 revert - - safe_add: - SAFE_ADD_WRAPPER() - safe_sub: - SAFE_SUB_WRAPPER() - safe_mul: - SAFE_MUL_WRAPPER() - safe_div: - SAFE_DIV_WRAPPER() - safe_mod: - SAFE_MOD_WRAPPER() -} - -/// @title SafeMath -/// @notice SPDX-License-Identifier: MIT -/// @author kadenzipfel -/// @notice Math module over Solidity's arithmetic operations with safety checks -/// @notice Adapted from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/math/SafeMath.sol) - -#include "../utils/Errors.huff" - -// Interface -#define function safeAdd(uint256,uint256) pure returns (uint256) -#define function safeSub(uint256,uint256) pure returns (uint256) -#define function safeMul(uint256,uint256) pure returns (uint256) -#define function safeDiv(uint256,uint256) pure returns (uint256) -#define function safeMod(uint256,uint256) pure returns (uint256) - -/// @notice Adds two numbers and reverts on overflow -#define macro SAFE_ADD() = takes (2) returns (1) { - // input stack // [num1, num2] - dup2 // [num2, num1, num2] - add // [result, num2] - dup1 // [result, result, num2] - swap2 // [num2, result, result] - gt // [is_overflow, result] - iszero // [is_not_overflow, result] - is_not_overflow jumpi // [result] - [ARITHMETIC_OVERFLOW] PANIC() - is_not_overflow: // [result] -} - -/// @notice Subtracts two numbers and reverts on underflow -#define macro SAFE_SUB() = takes (2) returns (1) { - // input stack // [num1, num2] - dup1 // [num1, num1, num2] - dup3 // [num2, num1, num1, num2] - gt // [is_underflow, num1, num2] - iszero // [is_not_underflow, num1, num2] - is_not_underflow jumpi // [num1, num2] - [ARITHMETIC_OVERFLOW] PANIC() - is_not_underflow: // [num1, num2] - sub // [result] -} - -/// @notice Multiplies two numbers and reverts on overflow -#define macro SAFE_MUL() = takes (2) returns (1) { - // input stack // [num1, num2] - dup1 // [num1, num1, num2] - is_not_zero jumpi // [num1, num2] - mul // [result] - 0x01 is_not_overflow jumpi - is_not_zero: // [num1, num2] - dup2 // [num2, num1, num2] - dup2 // [num1, num2, num1, num2] - mul // [result, num1, num2] - swap1 // [num1, result, num2] - dup2 // [result, num1, result, num2] - div // [div_check, result, num2] - swap1 // [result, div_check, num2] - swap2 // [num2, div_check, result] - eq // [is_not_overflow, result] - is_not_overflow jumpi // [result] - [ARITHMETIC_OVERFLOW] PANIC() - is_not_overflow: -} - -/// @notice Divides two numbers and reverts on division by zero -#define macro SAFE_DIV() = takes (2) returns (1) { - // input stack // [num1, num2] - 0x00 dup3 // [num2, 0, num1, num2] - gt // [is_not_div_zero, num1, num2] - is_not_div_zero jumpi - [DIVIDE_BY_ZERO] PANIC() - is_not_div_zero: - div // [result] -} - -/// @notice Divides two numbers and reverts on division by zero or modulo zero -#define macro SAFE_MOD() = takes (2) returns (1) { - // input stack // [num1, num2] - 0x00 dup3 // [num2, 0, num1, num2] - gt // [is_not_mod_zero, num1, num2] - is_not_mod_zero jumpi - [ARITHMETIC_OVERFLOW] PANIC() - is_not_mod_zero: - mod // [result] -} \ No newline at end of file diff --git a/src/math/__TEMP__hbpqkpduhnyeazoevkblfjmhdomwtqwoFixedPointMath.huff b/src/math/__TEMP__hbpqkpduhnyeazoevkblfjmhdomwtqwoFixedPointMath.huff deleted file mode 100644 index 323bcc19..00000000 --- a/src/math/__TEMP__hbpqkpduhnyeazoevkblfjmhdomwtqwoFixedPointMath.huff +++ /dev/null @@ -1,1093 +0,0 @@ -#define function mulDivDown(uint256,uint256,uint256) pure returns(uint256) -#define function mulDivUp(uint256,uint256,uint256) pure returns(uint256) -#define function mulWadDown(uint256,uint256) pure returns(uint256) -#define function mulWadUp(uint256,uint256) pure returns(uint256) -#define function divWadDown(uint256,uint256) pure returns(uint256) -#define function divWadUp(uint256,uint256) pure returns(uint256) -#define function rpow(uint256,uint256,uint256) pure returns(uint256) -#define function expWad(int256) pure returns(int256) -#define function powWad(int256,int256) pure returns(int256) -#define function lnWad(int256) pure returns(int256) -#define function sqrt(uint256) pure returns(uint256) -#define function log2(uint256) pure returns(uint256) -#define function cbrt(uint256) pure returns(uint256) - -#define macro MUL_DIV_DOWN_WRAPPER(fail) = takes (0) returns (0) { - 0x44 calldataload // [denominator] - 0x24 calldataload // [y, denominator] - 0x04 calldataload // [x, y, denominator] - MUL_DIV_DOWN(fail) // [result] - 0x00 mstore // [] - 0x20 0x00 return -} - -#define macro MUL_DIV_UP_WRAPPER(fail) = takes (0) returns (0) { - 0x44 calldataload // [denominator] - 0x24 calldataload // [y, denominator] - 0x04 calldataload // [x, y, denominator] - MUL_DIV_UP(fail) // [result] - 0x00 mstore // [] - 0x20 0x00 return -} - -#define macro MUL_WAD_DOWN_WRAPPER(fail) = takes (0) returns (0) { - 0x24 calldataload // [y] - 0x04 calldataload // [x, y] - MUL_WAD_DOWN(fail) // [result] - 0x00 mstore // [] - 0x20 0x00 return -} - -#define macro MUL_WAD_UP_WRAPPER(fail) = takes (0) returns (0) { - 0x24 calldataload // [y] - 0x04 calldataload // [x, y] - MUL_WAD_UP(fail) // [result] - 0x00 mstore // [] - 0x20 0x00 return -} - -#define macro DIV_WAD_DOWN_WRAPPER(fail) = takes (0) returns (0) { - 0x24 calldataload // [y] - 0x04 calldataload // [x, y] - DIV_WAD_DOWN(fail) // [result] - 0x00 mstore // [] - 0x20 0x00 return -} - -#define macro DIV_WAD_UP_WRAPPER(fail) = takes (0) returns (0) { - 0x24 calldataload // [y] - 0x04 calldataload // [x, y] - DIV_WAD_UP(fail) // [result] - 0x00 mstore // [] - 0x20 0x00 return -} - -#define macro RPOW_WRAPPER(fail) = takes (0) returns (0) { - 0x44 calldataload // [scalar] - 0x24 calldataload // [n, scalar] - 0x04 calldataload // [x, n, scalar] - RPOW(fail) // [result] - 0x00 mstore // [] - 0x20 0x00 return -} - -#define macro EXP_WAD_WRAPPER(fail) = takes (0) returns (0) { - 0x04 calldataload // [x] - EXP_WAD(fail) // [result] - 0x00 mstore - 0x20 0x00 return -} - -#define macro LN_WAD_WRAPPER(fail) = takes (0) returns (0) { - 0x04 calldataload // [x] - LN_WAD(fail) // [result] - 0x00 mstore - 0x20 0x00 return -} - -#define macro POW_WAD_WRAPPER(fail) = takes (0) returns (0) { - 0x24 calldataload // [y] - 0x04 calldataload // [x, y] - POW_WAD(fail) // [result] - 0x00 mstore // [] - 0x20 0x00 return -} - -#define macro SQRT_WRAPPER() = takes (0) returns (0) { - 0x04 calldataload // [x] - SQRT() // [result] - 0x00 mstore - 0x20 0x00 return -} - -#define macro LOG_2_WRAPPER(fail) = takes (0) returns (0) { - 0x04 calldataload // [x] - LOG_2(fail) // [result] - 0x00 mstore - 0x20 0x00 return -} - -#define macro CBRT_WRAPPER() = takes (0) returns (0) { - 0x04 calldataload - CBRT() - 0x00 mstore - 0x20 0x00 return -} - -#define macro MAIN() = takes (0) returns (0) { - pc calldataload 0xE0 shr - dup1 __FUNC_SIG(mulDivDown) eq mulDivDown jumpi - dup1 __FUNC_SIG(mulDivUp) eq mulDivUp jumpi - dup1 __FUNC_SIG(mulWadDown) eq mulWadDown jumpi - dup1 __FUNC_SIG(mulWadUp) eq mulWadUp jumpi - dup1 __FUNC_SIG(divWadDown) eq divWadDown jumpi - dup1 __FUNC_SIG(divWadUp) eq divWadUp jumpi - dup1 __FUNC_SIG(rpow) eq rpow jumpi - dup1 __FUNC_SIG(expWad) eq expWad jumpi - dup1 __FUNC_SIG(lnWad) eq lnWad jumpi - dup1 __FUNC_SIG(powWad) eq powWad jumpi - dup1 __FUNC_SIG(sqrt) eq sqrt jumpi - dup1 __FUNC_SIG(log2) eq logTwo jumpi - dup1 __FUNC_SIG(cbrt) eq cbrt jumpi - - - fail: - 0x00 0x00 revert - mulDivDown: - MUL_DIV_DOWN_WRAPPER(fail) - mulDivUp: - MUL_DIV_UP_WRAPPER(fail) - mulWadDown: - MUL_WAD_DOWN_WRAPPER(fail) - mulWadUp: - MUL_WAD_UP_WRAPPER(fail) - divWadDown: - DIV_WAD_DOWN_WRAPPER(fail) - divWadUp: - DIV_WAD_UP_WRAPPER(fail) - rpow: - RPOW_WRAPPER(fail) - expWad: - EXP_WAD_WRAPPER(fail) - lnWad: - LN_WAD_WRAPPER(fail) - powWad: - POW_WAD_WRAPPER(fail) - sqrt: - SQRT_WRAPPER() - logTwo: - LOG_2_WRAPPER(fail) - cbrt: - CBRT_WRAPPER() -} - -/// @title FixedPointMath -/// @notice SPDX-License-Identifier: MIT -/// @author clabby -/// @notice Minimal module for fixed-point number arithmetic -/// @notice Adapted from Solmate (https://github.com/transmissions11/solmate/blob/v7/src/utils/FixedPointMathLib.sol) - -#define constant WAD = 0x0de0b6b3a7640000 -#define constant DAY = 0x15180 - -//////////////////////////////////////////////////////////////// -// SIMPLIFIED FIXED POINT OPERATIONS // -//////////////////////////////////////////////////////////////// - -// https://github.com/transmissions11/solmate/blob/v7/src/utils/FixedPointMathLib.sol#L13 -#define macro MUL_WAD_DOWN(fail) = takes (2) returns (1) { - // Input stack: [x, y] - [WAD] // [WAD, x, y] - ARRANGE_STACK_MULWAD() // [x, y, WAD] - MUL_DIV_DOWN(fail) // [result] -} - -// https://github.com/transmissions11/solmate/blob/v7/src/utils/FixedPointMathLib.sol#L17 -#define macro MUL_WAD_UP(fail) = takes (2) returns (1) { - // Input stack: [x, y] - [WAD] // [WAD, x, y] - ARRANGE_STACK_MULWAD() // [x, y, WAD] - MUL_DIV_UP(fail) // [result] -} - -// https://github.com/transmissions11/solmate/blob/v7/src/utils/FixedPointMathLib.sol#L21 -#define macro DIV_WAD_DOWN(fail) = takes (2) returns (1) { - // Input stack: [x, y] - [WAD] // [WAD, x, y] - ARRANGE_STACK_DIVWAD() // [x, WAD, y] - MUL_DIV_DOWN(fail) -} - -// https://github.com/transmissions11/solmate/blob/v7/src/utils/FixedPointMathLib.sol#L25 -#define macro DIV_WAD_UP(fail) = takes (2) returns (1) { - // Input stack: [x, y] - [WAD] // [WAD, x, y] - ARRANGE_STACK_DIVWAD() // [x, WAD, y] - MUL_DIV_UP(fail) // [result] -} - -// https://github.com/transmissions11/solmate/blob/v7/src/utils/FixedPointMathLib.sol#L34 -#define macro EXP_WAD(fail) = takes (1) returns (1) { - // Input stack: [x] - - // When the result is < 0.5 we return zero. This happens when - // x <= floor(log(0.5e18) * 1e18) ~ -42e18 - 0xfffffffffffffffffffffffffffffffffffffffffffffffdb731c958f34d94c1 - dup2 // [x, 0xfff..., x] - sgt iszero // [x <= 0xfff..., x] - ret_zero jumpi // [x] - - // When the result is > (2**255 - 1) / 1e18 we can not represent it as an - // int. This happens when x >= floor(log((2**255 - 1) / 1e18) * 1e18) ~ 135. - 0x0755bf798b4a1bf1e5 // [0x0755bf798b4a1bf1e5, x] - dup2 // [x, 0x0755bf798b4a1bf1e5, x] - slt iszero // [x >= 0x0755bf798b4a1bf1e5, x] - jumpi // [x] - - // x is now in the range (-42, 136) * 1e18. Convert to (-42, 136) * 2**96 - // for more intermediate precision and a binary basis. This base conversion - // is a multiplication by 1e18 / 2**96 = 5**18 / 2**78. - 0x03782dace9d9 // [0x05 ** 0x12, x] - swap1 // [x, 0x05 ** 0x12] - 0x4e shl // [x << 0x4e, 0x05 ** 0x12] - sdiv // [x << 0x4e / 0x05 ** 0x12] - - // Reduce range of x to (-1/2 ln 2, 1/2 ln 2) * 2**96 by factoring out powers - // of two such that exp(x) = exp(x') * 2**k, where k is an integer. - // Solving this gives k = round(x / log(2)) and x' = x - k * log(2). - 0xb17217f7d1cf79abc9e3b398 - dup2 // [x, 0xb17217f7d1cf79abc9e3b398, x] - 0x60 shl // [x << 96, 0xb17217f7d1cf79abc9e3b398, x] - sdiv // [x << 96 / 0xb17217f7d1cf79abc9e3b398, x] - 0x7ffffff20f9306d2eea00000 // [2**95, x << 96 / 0xb17217f7d1cf79abc9e3b398, x] - add // [2**95 + x << 96 / 0xb17217f7d1cf79abc9e3b398, x] - 0x60 sar // [(2**95 + x << 96 / 0xb17217f7d1cf79abc9e3b398) >> 96, x] - - dup1 // [(2**95 + x << 96 / 0xb17217f7d1cf79abc9e3b398) >> 96, (2**95 + x << 96 / 0xb17217f7d1cf79abc9e3b398) >> 96, x] - 0xb17217f7d1cf79abc9e3b398 - mul // [((2**95 + x << 96 / 0xb17217f7d1cf79abc9e3b398) >> 96) * 0xb17217f7d1cf79abc9e3b398, (2**95 + x << 96 / 0xb17217f7d1cf79abc9e3b398) >> 96, x] - dup3 // [x, ((2**95 + x << 96 / 0xb17217f7d1cf79abc9e3b398) >> 96) * 0xb17217f7d1cf79abc9e3b398, (2**95 + x << 96 / 0xb17217f7d1cf79abc9e3b398) >> 96, x] - sub // [x (new), (2**95 + x << 96 / 0xb17217f7d1cf79abc9e3b398) >> 96, x] - swap2 pop // [k, x] - - // k is in the range [-61, 195]. - - // Evaluate using a (6, 7)-term rational approximation. - // p is made monic, we'll multiply by a scale factor later. - 0x10fe68e7fd37d0007b713f7650 - dup3 // [x, 0x10fe68e7fd37d0007b713f7650, k, x] - add // [y, k, x] - - 0x02d16720577bd19bf614176fe9ea - dup2 dup5 mul // [x * y, 0x02d16720577bd19bf614176fe9ea, y, k, x] - 0x60 sar // [(x * y) >> 0x60, 0x02d16720577bd19bf614176fe9ea, y, k, x] - add // [((x * y) >> 0x60) + 0x02d16720577bd19bf614176fe9ea, y, k, x] - swap1 pop // [y, k, x] - - 0x04a4fd9f2a8b96949216d2255a6c - dup4 dup3 add // [x + y, 0x04a4fd9f2a8b96949216d2255a6c, y, k, x] - sub // [x + y - 0x04a4fd9f2a8b96949216d2255a6c, y, k, x] - - dup2 // [y, x + y - 0x04a4fd9f2a8b96949216d2255a6c, y, k, x] - mul // [y * (x + y - 0x04a4fd9f2a8b96949216d2255a6c), y, k, x] - 0x60 sar // [(y * (x + y - 0x04a4fd9f2a8b96949216d2255a6c)) >> 0x60, y, k, x] - 0x0587f503bb6ea29d25fcb740196450 - add // [p, y, k, x] - - dup4 // [x, p, y, k, x] - mul // [x * p, y, k, x] - 0xd835ebba824c98fb31b83b2ca45c - 0x60 shl // [0xd835ebba824c98fb31b83b2ca45c << 0x60, x * p, y, k, x] - add // [p, y, k, x] - - // We leave p in 2**192 basis so we don't need to scale it back up for the division. - - 0x240c330e9fb2d9cbaf0fd5aafc - dup5 sub // [q, p, y, k, x] - - dup5 mul // [x * q, p, y, k, x] - 0x60 sar // [(x * q) >> 0x60, p, y, k, x] - 0x0277594991cfc85f6e2461837cd9 - add // [q, p, y, k, x] - - dup5 mul // [x * q, p, y, k, x] - 0x60 sar // [(x * q) >> 0x60, p, y, k, x] - 0x1a521255e34f6a5061b25ef1c9c4 swap1 - sub // [q, p, y, k, x] - - dup5 mul // [x * q, p, y, k, x] - 0x60 sar // [(x * q) >> 0x60, p, y, k, x] - 0xb1bbb201f443cf962f1a1d3db4a5 - add // [q, p, y, k, x] - - dup5 mul // [x * q, p, y, k, x] - 0x60 sar // [(x * q) >> 0x60, p, y, k, x] - 0x02c72388d9f74f51a9331fed693f15 swap1 - sub // [q, p, y, k, x] - - dup5 mul // [x * q, p, y, k, x] - 0x60 sar // [(x * q) >> 0x60, p, y, k, x] - 0x05180bb14799ab47a8a8cb2a527d57 - add // [q, p, y, k, x] - - // The q polynomial won't have zeros in the domain as all its roots are complex. - // No scaling is necessary because p is already 2**96 too large. - swap1 sdiv // [p / q (r), y, k, x] - - // r should be in the range (0.09, 0.25) * 2**96. - - // We now need to multiply r by: - // * the scale factor s = ~6.031367120. - // * the 2**k factor from the range reduction. - // * the 1e18 / 2**96 factor for base conversion. - // We do this all at once, with an intermediate result in 2**213 - // basis, so the final right shift is always by a positive amount. - - 0x029d9dc38563c32e5c2f6dc192ee70ef65f9978af3 - mul // [0x029d9... * r, y, k, x] - dup3 // [k, 0x029d9... * r, y, k, x] - 0xc3 sub // [0xc3 - k, 0x029d9... * r, y, k, x] - shr // [(0x029d9... * r) >> 0xc3 - k, y, k, x] - - // Clean stack - swap3 pop pop pop // [result] - - finish jump - - ret_zero: - 0x00 dup1 mstore - 0x20 0x00 return - finish: - // Return stack: [result] -} - -// https://github.com/transmissions11/solmate/blob/v7/src/utils/FixedPointMathLib.sol#L92 -#define macro LN_WAD(fail) = takes (1) returns (1) { - // Input stack: [x] - 0x00 dup2 sgt // [x > 0, x] - iszero // [x <= 0, x] - jumpi // [x] - - // We want to convert x from 10**18 fixed point to 2**96 fixed point. - // We do this by multiplying by 2**96 / 10**18. But since - // ln(x * C) = ln(x) + ln(C), we can simply do nothing here - // and add ln(2**96 / 10**18) at the end. - - // Reduce range of x to (1, 2) * 2**96 - // ln(2^k * x) = k * ln(2) + ln(x) - 0x60 // [0x60, x] - dup2 LOG_2(fail) // [log2(x), 0x60, x] - sub // [k, x] - - dup2 dup2 // [k, x, k, x] - 0x9f sub // [0x9f - k, x, k, x] - shl // [x << (0x9f - k), k, x] - 0x9f shr // [x_new, k, x] - swap2 pop // [k, x] - - // Evaluate using a (8, 8)-term rational approximation. - // p is made monic, we will multiply by a scale factor later. - dup2 // [x, k, x] - 0x29508e458543d8aa4df2abee78 - add // [p, k, x] - - dup3 mul // [p * x, k, x] - 0x60 sar // [(p * x) >> 0x60, k, x] - 0x0139601a2efabe717e604cbb4894 - add // [p, k, x] - - dup3 mul // [p * x, k, x] - 0x60 sar // [(p * x) >> 0x60, k, x] - 0x02247f7a7b6594320649aa03aba1 - add // [p, k, x] - - 0x8c3f38e95a6b1ff2ab1c3b3437 - swap1 dup4 mul // [p * x, 0x8c3f..., k, x] - 0x60 sar // [(p * x) >> 0x60, 0x8c3f..., k, x] - sub // [p, k, x] - - 0x02384773bdf1ac5676facced6091 - swap1 dup4 mul // [p * x, 0x0238..., k, x] - 0x60 sar // [(p * x) >> 0x60, 0x0238..., k, x] - sub // [p, k, x] - - 0xb9a025d814b29c212b8b1a07ce - swap1 dup4 mul // [p * x, 0xb9a0..., k, x] - 0x60 sar // [(p * x) >> 0x60, 0xb9a0..., k, x] - sub // [p, k, x] - - 0x0a09507084cc699bb0e71ea86a - 0x60 shl // [0x0a09... << 0x60, p, k, x] - swap1 // [p, 0x0a09... << 0x60, k, x] - dup4 mul // [p * x, 0x0a09... << 0x60, k, x] - sub // [p, k, x] - - // We leave p in 2**192 basis so we don't need to scale it back up for the division. - // q is monic by convention. - dup3 // [x, p, k, x] - 0x465772b2bbbb5f824b15207a30 - add // [q, p, k, x] - - dup4 mul // [q * x, p, k, x] - 0x60 sar // [(q * x) >> 0x60, p, k, x] - 0x0388eaa27412d5aca026815d636e - add // [q, p, k, x] - - dup4 mul // [q * x, p, k, x] - 0x60 sar // [(q * x) >> 0x60, p, k, x] - 0x0df99ac502031bf953eff472fdcc - add // [q, p, k, x] - - dup4 mul // [q * x, p, k, x] - 0x60 sar // [(q * x) >> 0x60, p, k, x] - 0x13cdffb29d51d99322bdff5f2211 - add // [q, p, k, x] - - dup4 mul // [q * x, p, k, x] - 0x60 shr // [(q * x) >> 0x60, p, k, x] - 0x0a0f742023def783a307a986912e - add // [q, p, k, x] - - dup4 mul // [q * x, p, k, x] - 0x60 sar // [(q * x) >> 0x60, p, k, x] - 0x01920d8043ca89b5239253284e42 - add // [q, p, k, x] - - dup4 mul // [q * x, p, k, x] - 0x60 sar // [(q * x) >> 0x60, p, k, x] - 0x0b7a86d7375468fac667a0a527 - add // [q, p, k, x] - - // The q polynomial is known not to have zeros in the domain. - // No scaling required because p is already 2**96 too large. - swap1 sdiv // [p / q (r), k, x] - - // r is in the range (0, 0.125) * 2**96 - - // Finalization, we need to: - // * multiply by the scale factor s = 5.549... - // * add ln(2**96 / 10**18) - // * add k * ln(2) - // * multiply by 10**18 / 2**96 = 5**18 >> 78 - - // mul s * 5e18 * 2**96, base is now 5**18 * 2**192 - 0x1340daa0d5f769dba1915cef59f0815a5506 mul - - // add ln(2) * k * 5e18 * 2**192 - swap1 // [k, r, x] - 0x0267a36c0c95b3975ab3ee5b203a7614a3f75373f047d803ae7b6687f2b3 - mul // [k * 0x0267..., r, x] - add // [r, x] - - // add ln(2**96 / 10**18) * 5e18 * 2**192 - 0x57115e47018c7177eebf7cd370a3356a1b7863008a5ae8028c72b8864284 - add // [r, x] - - // base conversion: mul 2**18 / 2**192 - 0xAE sar // [r >> 0xAE, x] - - finish jump - - finish: - // Clean stack - swap1 pop - // Return stack: [result] -} - -// https://github.com/transmissions11/solmate/blob/v7/src/utils/FixedPointMathLib.sol#L29 -#define macro POW_WAD(fail) = takes (2) returns (1) { - // Input Stack: [x, y] - LN_WAD(fail) // [lnWad(x), y] - mul // [lnWad(x) * y] - [WAD] swap1 // [lnWad(x) * y, 1e18] - sdiv // [(lnWad(x) * y) / 1e18] - EXP_WAD(fail) // [result] -} - -//////////////////////////////////////////////////////////////// -// LOW LEVEL FIXED POINT OPERATIONS // -//////////////////////////////////////////////////////////////// - -// https://github.com/transmissions11/solmate/blob/main/src/utils/FixedPointMathLib.sol#L34 -#define macro MUL_DIV_DOWN(fail) = takes (3) returns (1) { - // Input stack: [x, y, denominator] - dup1 dup3 mul // [x * y, x, y, denominator] - dup1 // [x * y, x * y, x, y, denominator] - swap2 dup1 // [x, x, x * y, x * y, y, denominator] - - iszero // [x == 0, x, x * y, x * y, y, denominator] - swap2 // [x * y, x, x == 0, x * y, y, denominator] - div // [(x * y) / x, x == 0, x * y, y, denominator] - dup4 eq // [y == (x * y) / x, x == 0, x * y, y, denominator] - or // [y == (x * y) / x | x == 0, x * y, y, denominator] - swap2 pop // [x * y, y == (x * y) / x | x == 0, denominator] - swap1 dup3 // [denominator, y == (x * y) / x | x == 0, x * y, denominator] - iszero iszero // [denominator != 0, y == (x * y) / x | x == 0, x * y, denominator] - and // [denominator != 0 & y == (x * y) / x | x == 0, x * y, denominator] - - iszero jumpi // [x * y, denominator] - - div // [(x * y) / denominator] - // Return stack: [(x * y) / denominator] -} - -// https://github.com/transmissions11/solmate/blob/main/src/utils/FixedPointMathLib.sol#L53 -#define macro MUL_DIV_UP(fail) = takes (3) returns (1) { - // Input stack: [x, y, denominator] - dup1 dup3 mul // [x * y, x, y, denominator] - dup1 // [x * y, x * y, x, y, denominator] - swap2 dup1 // [x, x, x * y, x * y, y, denominator] - - iszero // [x == 0, x, x * y, x * y, y, denominator] - swap2 // [x * y, x, x == 0, x * y, y, denominator] - div // [(x * y) / x, x == 0, x * y, y, denominator] - dup4 eq // [y == (x * y) / x, x == 0, x * y, y, denominator] - or // [y == (x * y) / x | x == 0, x * y, y, denominator] - swap2 pop // [x * y, y == (x * y) / x | x == 0, denominator] - swap1 dup3 // [denominator, y == (x * y) / x | x == 0, x * y, denominator] - iszero iszero // [denominator != 0, y == (x * y) / x | x == 0, x * y, denominator] - and // [denominator != 0 & y == (x * y) / x | x == 0, x * y, denominator] - - iszero jumpi // [x * y, denominator] - - dup1 // [x * y, x * y, denominator] - iszero iszero // [x * y != 0, x * y, denominator] - - dup3 // [denominator, x * y != 0, x * y, denominator] - 0x01 // [1, denominator, x * y != 0, x * y, denominator] - dup4 // [x * y, 1, denominator, x * y != 0, x * y, denominator] - sub // [x * y - 1, denominator, x * y != 0, x * y, denominator] - div // [x * y - 1 / denominator, x * y != 0, x * y, denominator] - 0x01 // [1, x * y - 1 / denominator, x * y != 0, x * y, denominator] - add // [(x * y - 1 / denominator) + 1, x * y != 0, x * y, denominator] - - mul // [((x * y - 1 / denominator) + 1) * (x * y != 0), x * y, denominator] - - // Clear extra stack items before continuing - swap2 // [denominator, x * y, ((x * y - 1 / denominator) + 1) * (x * y != 0)] - pop pop // [((x * y - 1 / denominator) + 1) * (x * y != 0)] - // Return stack: [((x * y - 1 / denominator) + 1) * (x * y != 0)] -} - -// https://github.com/transmissions11/solmate/blob/main/src/utils/FixedPointMathLib.sol#L74 -// TODO: Optimize, works but not great -#define macro RPOW(fail) = takes (3) returns (1) { - // Input stack: [x, n, scalar] - dup1 // [x, x, n, scalar] - default jumpi // Jump to "default" if x != 0 - - // TODO: Fix hack- code following `finish` label pops four items off of - // the stack, so we fill it with extra items here in order to return - // the scalar or 0. - - dup3 dup4 // [scalar, scalar, x, n, scalar] - dup4 iszero // [n == 0, scalar, scalar, x, n, scalar] - finish jumpi // If n == 0 && x == 0, return the scalar (0 ** 0 = 1). - - // 0 ** n = 0 - 0x00 dup1 finish jump // Finish execution - - default: - dup3 // [scalar, x, n, scalar] - 0x01 shr // [scalar >> 1, x, n, scalar] - - dup4 // [result, scalar >> 1, x, n, scalar] - 0x02 // [2, result, scalar >> 1, x, n, scalar] - dup5 // [n, 2, result, scalar >> 1, x, n, scalar] - mod // [n % 2, result, scalar >> 1, x, n, scalar] - - // Set result to scalar for now if n % 2 is even - iszero loop jumpi // [result, scalar >> 1, x, n, scalar]] - - // Set result to x for now if n % 2 is odd - pop dup2 // [result, scalar >> 1, x, n, scalar] - loop: - dup4 // [n, result, scalar >> 1, x, n, scalar] - iszero finish jumpi // If n == 0, the loop is finished. - - // Divide n by 2 - dup4 // [n, result, scalar >> 1, x, n, scalar] - 0x01 shr // [n >> 1, result, scalar >> 1, x, n, scalar] - swap4 pop // [result, scalar >> 1, x, n, scalar] - - // Revert if x ** 2 will overflow. - dup3 // [x, result, scalar >> 1, x, n, scalar] - 0x80 shr // [x >> 128, result, scalar >> 1, x, n, scalar] - - // Square x and duplicate it on the stack for use later. - dup4 // [x, x >> 128, result, scalar >> 1, x, n, scalar] - dup1 mul // [x * x, x >> 128, result, scalar >> 1, x, n, scalar] - dup1 // [x * x, x * x, x >> 128, result, scalar >> 1, x, n, scalar] - - // Add x ** 2 to scalar >> 1 - dup5 // [scalar >> 1, x * x, x * x, x >> 128, result, scalar >> 1, x, n, scalar] - add // [(scalar >> 1) + (x * x), x * x, x >> 128, result, scalar >> 1, x, n, scalar] - - // Revert if x ** 2 + scalar >> 1 overflowed - swap2 // [x >> 128, x * x, (scalar >> 1) + (x * x), result, scalar >> 1, x, n, scalar] - swap1 // [x * x, x >> 128, (scalar >> 1) + (x * x), result, scalar >> 1, x, n, scalar] - dup3 lt // [(scalar >> 1) + (x * x) < x * x, x >> 128, (scalar >> 1) + (x * x), result, scalar >> 1, x, n, scalar] - or jumpi // [(scalar >> 1) + (x * x), result, scalar >> 1, x, n, scalar] - - // Set x to ((scalar >> 1) + (x * x)) / scalar - dup6 // [scalar, (scalar >> 1) + (x * x), result, scalar >> 1, x, n, scalar] - swap1 // [(scalar >> 1) + (x * x), scalar, result, scalar >> 1, x, n, scalar] - div // [((scalar >> 1) + (x * x)) / scalar, result, scalar >> 1, x, n, scalar] - swap3 pop // [result, scalar >> 1, x, n, scalar] - - 0x02 // [2, result, scalar >> 1, x, n, scalar] - dup5 // [n, 2, result, scalar >> 1, x, n, scalar] - mod // [n % 2, result, scalar >> 1, x, n, scalar] - - // If n is even, continue loop - iszero loop jumpi - // If n is odd, continue logic - - // Multiply x * result - dup1 // [result, result, scalar >> 1, x, n, scalar] - dup4 // [x, result, result, scalar >> 1, x, n, scalar] - mul // [x * result, result, scalar >> 1, x, n, scalar] - dup1 // [x * result, x * result, result, scalar >> 1, x, n, scalar] - dup1 // [x * result, x * result, x * result, result, scalar >> 1, x, n, scalar] - - // Check if x * result overflowed - dup6 // [x, x * result, x * result, x * result, result, scalar >> 1, x, n, scalar] - swap1 // [x * result, x, x * result, x * result, result, scalar >> 1, x, n, scalar] - div // [x * result / x, x * result, x * result, result, scalar >> 1, x, n, scalar] - dup4 // [result, x * result / x, x * result, x * result, result, scalar >> 1, x, n, scalar] - eq iszero // [result != (x * result / x), x * result, x * result, result, scalar >> 1, x, n, scalar] - dup6 // [x, result != (x * result / x), x * result, x * result, result, scalar >> 1, x, n, scalar] - iszero iszero // [x != 0, result != (x * result / x), x * result, x * result, result, scalar >> 1, x, n, scalar] - and // [x != 0 & result != (x * result / x), x * result, x * result, result, scalar >> 1, x, n, scalar] - swap2 // [x * result, x * result, x != 0 & result != (x * result / x), result, scalar >> 1, x, n, scalar] - - // Round to the nearest number - dup5 // [scalar >> 1, x * result, x * result, x != 0 & result != (x * result / x), result, scalar >> 1, x, n, scalar] - add // [(scalar >> 1) + (x * result), x * result, x != 0 & result != (x * result / x), result, scalar >> 1, x, n, scalar] - - // Check if x ** 2 + scalar >> 1 overflowed - swap2 // [x != 0 & result != (x * result / x), x * result, (scalar >> 1) + (x * result), result, scalar >> 1, x, n, scalar] - swap1 // [x * result, x != 0 & result != (x * result / x), (scalar >> 1) + (x * result), result, scalar >> 1, x, n, scalar] - dup3 lt // [(scalar >> 1) + (x * result) < x * result, x != 0 & result != (x * result / x), (scalar >> 1) + (x * result), result, scalar >> 1, x, n, scalar] - - // Revert if ((scalar >> 1) + (x * result)) < x * result OR x != 0 & result != (x * result / x) - or jumpi // [(scalar >> 1) + (x * result), result, scalar >> 1, x, n, scalar] - - // Scale rounded result - dup6 // [scalar, (scalar >> 1) + (x * result), result, scalar >> 1, x, n, scalar] - swap1 // [(scalar >> 1) + (x * result), scalar, result, scalar >> 1, x, n, scalar] - div // [(scalar >> 1) + (x * result)) / scalar, result, scalar >> 1, x, n, scalar] - swap1 pop // [result, scalar >> 1, x, n, scalar] - - loop jump // Continue loop - // Return result - finish: - // Clean Stack - swap4 // [scalar, scalar >> 1, x, n, result] - pop pop pop pop // [result] - // Return stack: [result] -} - -//////////////////////////////////////////////////////////////// -// GENERAL NUMBER UTILITIES // -//////////////////////////////////////////////////////////////// - -// https://github.com/transmissions11/solmate/blob/v7/src/utils/FixedPointMathLib.sol#L288 -#define macro SQRT() = takes (1) returns (1) { - // Input stack: [x] - - // We start y at x, which will help us make our initial estimate. - dup1 // [y, x] - - // The "correct" value is 1, but this saves a multiplication later. - 0xb5 // [0xb5, y, x] - - 0x10000000000000000000000000000000000 - dup3 // [y, 0x1000..., z, y, x] - lt // [y < 0x1000..., z, y, x] - continue_1 jumpi // [z, y, x] - - 0x40 shl // [z << 0x40, y, x] - swap1 // [y, z << 0x40, x] - 0x80 shr // [y >> 0x80, z << 0x40, x] - swap1 // [z << 0x40, y >> 0x80, x] - - continue_1: - - 0x1000000000000000000 - dup3 // [y, 0x1000..., z, y, x] - lt // [y < 0x1000..., z, y, x] - continue_2 jumpi // [z, y, x] - - 0x20 shl // [z << 0x20, y, x] - swap1 // [y, z << 0x20, x] - 0x40 shr // [y >> 0x40, z << 0x20, x] - swap1 // [z << 0x20, y >> 0x40, x] - - continue_2: - - 0x10000000000 - dup3 // [y, 0x1000..., z, y, x] - lt // [y < 0x1000..., z, y, x] - continue_3 jumpi // [z, y, x] - - 0x10 shl // [z << 0x10, y, x] - swap1 // [y, z << 0x10, x] - 0x20 shr // [y >> 0x20, z << 0x10, x] - swap1 // [z << 0x10, y >> 0x20, x] - - continue_3: - - 0x1000000 - dup3 // [y, 0x1000..., z, y, x] - lt // [y < 0x1000..., z, y, x] - continue_4 jumpi // [z, y, x] - - 0x08 shl // [z << 0x08, y, x] - swap1 // [y, z << 0x08, x] - 0x10 shr // [y >> 0x10, z << 0x08, x] - swap1 // [z << 0x08, y >> 0x10, x] - - continue_4: - - // Goal was to get z*z*y within a small factor of x. More iterations could - // get y in a tighter range. Currently, we will have y in [256, 256*2^16). - // We ensured y >= 256 so that the relative difference between y and y+1 is small. - // That's not possible if x < 256 but we can just verify those cases exhaustively. - - // Now, z*z*y <= x < z*z*(y+1), and y <= 2^(16+8), and either y >= 256, or x < 256. - // Correctness can be checked exhaustively for x < 256, so we assume y >= 256. - // Then z*sqrt(y) is within sqrt(257)/sqrt(256) of sqrt(x), or about 20bps. - - // For s in the range [1/256, 256], the estimate f(s) = (181/1024) * (s+1) is in the range - // (1/2.84 * sqrt(s), 2.84 * sqrt(s)), with largest error when s = 1 and when s = 256 or 1/256. - - // Since y is in [256, 256*2^16), let a = y/65536, so that a is in [1/256, 256). Then we can estimate - // sqrt(y) using sqrt(65536) * 181/1024 * (a + 1) = 181/4 * (y + 65536)/65536 = 181 * (y + 65536)/2^18. - - // There is no overflow risk here since y < 2^136 after the first branch above. - - // A mul is saved from starting z at 181. - swap1 // [y, z, x] - 0x010000 add // [y + 0x010000, z, x] - mul // [(y + 0x010000) * z, x] - 0x12 shr // [((y + 0x010000) * z) >> 0x12, x] - - // Given the worst case multiplicative error of 2.84 above, 7 iterations should be enough. - dup1 dup3 // [x, z, z, x] - div // [x / z, z, x] - add // [x / z + z, x] - 0x01 shr // [(x / z + z) >> 0x01, x] - - dup1 dup3 // [x, z, z, x] - div // [x / z, z, x] - add // [x / z + z, x] - 0x01 shr // [(x / z + z) >> 0x01, x] - - dup1 dup3 // [x, z, z, x] - div // [x / z, z, x] - add // [x / z + z, x] - 0x01 shr // [(x / z + z) >> 0x01, x] - - dup1 dup3 // [x, z, z, x] - div // [x / z, z, x] - add // [x / z + z, x] - 0x01 shr // [(x / z + z) >> 0x01, x] - - dup1 dup3 // [x, z, z, x] - div // [x / z, z, x] - add // [x / z + z, x] - 0x01 shr // [(x / z + z) >> 0x01, x] - - dup1 dup3 // [x, z, z, x] - div // [x / z, z, x] - add // [x / z + z, x] - 0x01 shr // [(x / z + z) >> 0x01, x] - - dup1 dup3 // [x, z, z, x] - div // [x / z, z, x] - add // [x / z + z, x] - 0x01 shr // [(x / z + z) >> 0x01, x] - - // If x+1 is a perfect square, the Babylonian method cycles between - // floor(sqrt(x)) and ceil(sqrt(x)). This statement ensures we return floor. - // See: https://en.wikipedia.org/wiki/Integer_square_root#Using_only_integer_division - // Since the ceil is rare, we save gas on the assignment and repeat division in the rare case. - // If you don't care whether the floor or ceil square root is returned, you can remove this statement. - dup1 dup1 swap3 // [x, z, z, z] - div // [x / z, z, z] - lt // [(x / z) < z, z] - swap1 sub // [z - (x / z) < z] -} - -// https://github.com/transmissions11/solmate/blob/v7/src/utils/FixedPointMathLib.sol#L352 -#define macro LOG_2(fail) = takes (1) returns (1) { - // Input stack: [x] - - dup1 iszero // [x == 0, x] - jumpi // [x] - - dup1 // [x, x] - 0xffffffffffffffffffffffffffffffff - lt // [0xffff... < x, x] - 0x07 shl // [r, x] - - dup2 dup2 // [r, x, r, x] - shr // [x >> r, r, x] - 0xffffffffffffffff lt // [0xffff... < (x >> r), r, x] - 0x06 shl // [(0xffff... < (x >> r)) << 6, r, x] - or // [r | (0xffff... < (x >> r)) << 6, x] - - dup2 dup2 // [r, x, r, x] - shr // [x >> r, r, x] - 0xffffffff lt // [0xffff... < (x >> r), r, x] - 0x05 shl // [(0xffff... < (x >> r)) << 5, r, x] - or // [r | (0xffff... < (x >> r)) << 5, x] - - dup2 dup2 // [r, x, r, x] - shr // [x >> r, r, x] - 0xffff lt // [0xffff < (x >> r), r, x] - 0x04 shl // [(0xffff < (x >> r)) << 4, r, x] - or // [r | (0xffff < (x >> r)) << 4, x] - - dup2 dup2 // [r, x, r, x] - shr // [x >> r, r, x] - 0xff lt // [0xff < (x >> r), r, x] - 0x03 shl // [(0xff < (x >> r)) << 3, r, x] - or // [r | (0xff < (x >> r)) << 3, x] - - dup2 dup2 // [r, x, r, x] - shr // [x >> r, r, x] - 0x0f lt // [0x0f < (x >> r), r, x] - 0x02 shl // [(0x0f < (x >> r)) << 2, r, x] - or // [r | (0x0f < (x >> r)) << 2, x] - - dup2 dup2 // [r, x, r, x] - shr // [x >> r, r, x] - 0x03 lt // [0x03 < (x >> r), r, x] - 0x01 shl // [(0x03 < (x >> r)) << 1, r, x] - or // [r | (0x03 < (x >> r)) << 1, x] - - dup2 dup2 // [r, x, r, x] - shr // [x >> r, r, x] - 0x01 lt // [0x01 < (x >> r), r, x] - or // [r, x] - swap1 pop // [r] - - // Return stack: // [result] -} - -/// @notice Calculates the cube root of the stack input -/// Credits: https://github.com/Vectorized/solady/blob/main/src/utils/FixedPointMathLib.sol#L504 -#define macro CBRT() = takes (1) returns (1) { - // Input Stack: [x] - - // r construction - - dup1 // [x, x] - 0xffffffffffffffffffffffffffffffff // [0xffffffffffffffffffffffffffffffff, x, x] - lt // [0xffffffffffffffffffffffffffffffff< x, x] - 0x7 shl // [0xffffffffffffffffffffffffffffffff < x << 7, x] - // r = 0xffffffffffffffffffffffffffffffff < x << 7 - - dup2 dup2 // [r, x, r, x] - shr // [x >> r, r, x] - 0xffffffffffffffff // [0xffffffffffffffff, x >> r, r, x] - lt // [0xffffffffffffffff < x >> r, r, x] - 0x6 shl // [0xffffffffffffffff < x >> r << 6, r, x] - or // [0xffffffffffffffff < x >> r << 6 | r, x] - // r' = r | (0xffffffffffffffff < (x >> r)) << 6 - - dup2 dup2 // [r', x, r', x] - shr // [x >> r', r', x] - 0xffffffff // [0xffffffff, x >> r', r', x] - lt // [0xffffffff < x >> r, r', x] - 0x5 shl // [0xffffffff < x >> r << 5, r', x] - or // [0xffffffff < x >> r << 5 | r', x] - // r' = r' | 0xffffffff < x >> r << 5 - - dup2 dup2 // [r', x, r', x] - shr // [x >> r', r', x] - 0xffff // [0xffff, x >> r', r',x] - lt // [0xffff < x >> r', r', x] - 0x4 shl // [0xffff < x >> r' << 4, r', x] - or // [0xffff < x >> r' << 4 | r', x] - // r' = r' | 0xffff < x >> r' << 4 - - dup2 dup2 // [r', x, r', x] - shr // [x >> r', r', x] - 0xff // [0xff, x >> r', r', x] - lt // [0xff < x >> r', r', x] - 0x3 shl // [0xff < x >> r' << 3, r', x] - or // [0xff < x >> r' << 3 | r', x] - // r' = r'|0xff < x >> r' << 3 - - // z construction - - 0xff // [0xff, r', x] - dup3 dup3 // [r', x, 0xff, r', x] - shr // [x >> r', 0xff, r', x] - 0xf // [0xf, x >> r', 0xff, r', x] - lt // [0xf < x >> r', 0xff, r', x] - 0x3 // [3, 0xf < x >> r', 0xff, r', x] - dup4 // [r', 3, 0xf < x >> r', 0xff, r', x] - div // [r' / 3, 0xf < x >> r', 0xff, r', x] - add // [r' / 3 + 0xf < x >> r', 0xff, r', x] - shl // [0xff << r' / 3 + 0xf < x >> r', r', x] - // z = 0xff << r' / 3 + 0xf < x >> r' - - 0x3 // [0x3, z, r', x] - swap1 // [z, 0x3, r', x] - swap2 // [r', 0x3, z, x] - mod // [r' % 3, z, x] - 0x7f624b // [0x7f624b, r' % 3, z, x] - 0xe8 // [0xe8, 0x7f624b, r' % 3, z, x] - shl // [0x7f624b << 0xe8, r' % 3, z, x] - swap1 // [r' % 3, 0x7f624b << 0xe8, z, x] - byte // [byte(r' % 3, 0x7f624b << 0xe8), z, x] - swap1 // [z, byte(r' % 3, 0x7f624b << 0xe8), x] - div // [z / byte(r' % 3, 0x7f624b << 0xe8), x] - // z' = z / byte(r' % 3, 0xe8 << 0x7f624b) - - // Round 1 / 7 - 0x3 // [3, z', x] - swap1 dup1 // [z', z', 3, x] - dup1 dup1 // [z', z', z', z', 3, x] - mul // [z' * z', z', z', 3, x] - dup5 // [x, z' * z', z', z', 3, x] - div add // [x / z' * z' + z', z', 3, x] - add div // [((x / (z' * z')) + z') + z') / 3, x] - // z' = ((x / (z' * z'))+ z') + z') / 3 - - // Round 2 / 7 - 0x3 // [3, z', x] - swap1 dup1 // [z', z', 3, x] - dup1 dup1 // [z', z', z', z', 3, x] - mul // [z' * z', z', z', 3, x] - dup5 // [x, z' * z', z', z', 3, x] - div add // [x / z' * z' + z', z', 3, x] - add div // [((x / (z' * z'))+ z') + z') / 3, x] - // z' = ((x / (z' * z'))+ z') + z') / 3 - - // Round 3 / 7 - 0x3 // [3, z', x] - swap1 dup1 // [z', z', 3, x] - dup1 dup1 // [z', z', z', z', 3, x] - mul // [z' * z', z', z', 3, x] - dup5 // [x, z' * z', z', z', 3, x] - div add // [x / z' * z' + z', z', 3, x] - add div // [((x / (z' * z'))+ z') + z') / 3, x] - // z' = ((x / (z' * z'))+ z') + z') / 3 - - // Round 4 / 7 - 0x3 // [3, z', x] - swap1 dup1 // [z', z', 3, x] - dup1 dup1 // [z', z', z', z', 3, x] - mul // [z' * z', z', z', 3, x] - dup5 // [x, z' * z', z', z', 3, x] - div add // [x / z' * z' + z', z', 3, x] - add div // [((x / (z' * z'))+ z') + z') / 3, x] - // z' = ((x / (z' * z'))+ z') + z') / 3 - - // Round 5 / 7 - 0x3 // [3, z', x] - swap1 dup1 // [z', z', 3, x] - dup1 dup1 // [z', z', z', z', 3, x] - mul // [z' * z', z', z', 3, x] - dup5 // [x, z' * z', z', z', 3, x] - div add // [x / z' * z' + z', z', 3, x] - add div // [((x / (z' * z'))+ z') + z') / 3, x] - // z' = ((x / (z' * z'))+ z') + z') / 3 - - // Round 6 / 7 - 0x3 // [3, z', x] - swap1 dup1 // [z', z', 3, x] - dup1 dup1 // [z', z', z', z', 3, x] - mul // [z' * z', z', z', 3, x] - dup5 // [x, z' * z', z', z', 3, x] - div add // [x / z' * z' + z', z', 3, x] - add div // [((x / (z' * z'))+ z') + z') / 3, x] - // z' = ((x / (z' * z'))+ z') + z') / 3 - - // Round 7 / 7 - 0x3 // [3, z', x] - swap1 dup1 // [z', z', 3, x] - dup1 dup1 // [z', z', z', z', 3, x] - mul // [z' * z', z', z', 3, x] - dup5 // [x, z' * z', z', z', 3, x] - div add // [x / z' * z' + z', z', 3, x] - add div // [((x / (z' * z'))+ z') + z') / 3, x] - // z' = ((x / (z' * z'))+ z') + z') / 3 - - // Final operation - dup1 swap2 // [x, z', z'] - dup2 dup1 // [z', z', x, z', z'] - mul // [z' * z', x, z', z'] - swap1 // [x, z' * z', z', z'] - div // [x / (z' * z'), z', z'] - lt // [x / (z' * z') < z', z'] - swap1 sub // [z' - (x / (z' * z') < z')] - - // Return stack: [result: z'] -} - -//////////////////////////////////////////////////////////////// -// HELPER MACROS // -//////////////////////////////////////////////////////////////// - -#define macro ARRANGE_STACK_MULWAD() = takes (3) returns (3) { - // Input stack: [WAD, x, y] - swap2 // [y, x, WAD] - swap1 // [x, y, WAD] -} - -#define macro ARRANGE_STACK_DIVWAD() = takes (3) returns (3) { - // Input stack: [WAD, x, y] - swap1 // [x, WAD, y] -} - -// TESTS - -#define macro TEST_ASSERT_EQ() = { - eq continue jumpi - 0x00 dup1 revert - continue: -} - -// test wad mul for positive numbers -#define test TEST_WAD_DIV() = { - 0xDE0B6B3A7640000 // [y (1e18)] - 0x1BC16D674EC80000 // [x (2e18),y] - WAD_MUL(fail) // result - 0x1BC16D674EC80000 - TEST_ASSERT_EQ() - continue jump - - fail: - FAIL() - continue: -} - -// test wad mul for positive numbers -#define test TEST_WAD_MUL() = { - 0x0DE0B6B3A7640000 // [y (1e18)] - 0x1BC16D674EC80000 // [x (2e18), y] - WAD_MUL(fail) // result - - 0x1BC16D674EC80000 - TEST_ASSERT_EQ() - continue jump - // catch jump label - fail: - 0x00 dup1 revert - continue: -} - -#define test FAIL_WAD_MUL() = { - 0xF0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF - 0x20 - WAD_MUL(fail) - 0x00 dup1 revert - - // succeed if fails - fail: -} - -#define test FAIL_WAD_DIV() = { - 0x00 - 0x0DE0B6B3A7640000 - WAD_DIV(fail) - 0x00 dup1 revert - - // succeed if fails - fail: -} - - -#define test TEST_TO_WAD_UNSAFE() = { - // Test 0x2 * WAD = 2e18 - 0x02 - TO_WAD_UNSAFE() - 0x1BC16D674EC80000 // [2*e18] - TEST_ASSERT_EQ() -} diff --git a/src/math/__TEMP__ohdnimzopkbndglbmvjbzlrpyrrzphnrTrigonometry.huff b/src/math/__TEMP__ohdnimzopkbndglbmvjbzlrpyrrzphnrTrigonometry.huff deleted file mode 100644 index a74aa9a7..00000000 --- a/src/math/__TEMP__ohdnimzopkbndglbmvjbzlrpyrrzphnrTrigonometry.huff +++ /dev/null @@ -1,218 +0,0 @@ -#define function sin(uint256) pure returns (int256) -#define function cos(uint256) pure returns (int256) - -#define macro SIN_WRAPPER() = takes (0) returns (0) { - 0x04 calldataload // [angle] - SIN() // [sin(angle)] - 0x00 mstore // [] - 0x20 0x00 return -} - -#define macro COS_WRAPPER() = takes (0) returns (0) { - 0x04 calldataload // [angle] - COS() // [cos(angle)] - 0x00 mstore // [] - 0x20 0x00 return -} - -#define macro MAIN() = takes (0) returns (0) { - pc calldataload 0xE0 shr - dup1 __FUNC_SIG(sin) eq sin jumpi - dup1 __FUNC_SIG(cos) eq cos jumpi - - 0x00 dup1 revert - - sin: - SIN_WRAPPER() - cos: - COS_WRAPPER() -} - -/// @title Trigonometry -/// @notice SPDX-License-Identifier: MIT -/// @author mds1 -/// @author clabby -/// @notice Basic trigonometry functions where inputs and outputs are integers. -/// Inputs are specified in radians scaled by 1e18, and similarly outputs are scaled by 1e18. -/// @notice Adapted from mds1 (https://github.com/mds1/solidity-trigonometry/blob/main/src/Trigonometry.sol) - -//////////////////////////////////////////////////////////////// -// CONSTANTS // -//////////////////////////////////////////////////////////////// - -// Table index into the trigonometric table -#define constant INDEX_WIDTH = 0x08 - -// Interpolation between successive entries in the table -#define constant INTERP_WIDTH = 0x10 -#define constant INDEX_OFFSET = 0x14 -#define constant INTERP_OFFSET = 0x04 -#define constant ANGLES_IN_CYCLE = 0x40000000 -#define constant QUADRANT_HIGH_MASK = 0x20000000 -#define constant QUADRANT_LOW_MASK = 0x10000000 -#define constant SINE_TABLE_SIZE = 0x100 - -// Pi as an 18 decimal value, which is plenty of accuracy: "For JPL's highest accuracy calculations, which are for -// interplanetary navigation, we use 3.141592653589793: https://www.jpl.nasa.gov/edu/news/2016/3/16/how-many-decimals-of-pi-do-we-really-need/ -#define constant PI = 0x2B992DDFA23249D6 -#define constant TWO_PI = 0x57325BBF446493AC -#define constant PI_OVER_TWO = 0x15CC96EFD1192500 - -// The constant sine lookup table was generated by generate_trigonometry.py. We must use a constant -// bytes array because constant arrays are not supported in Solidity. Each entry in the lookup -// table is 4 bytes. Since we're using 32-bit parameters for the lookup table, we get a table size -// of 2^(32/4) + 1 = 257, where the first and last entries are equivalent (hence the table size of -// 256 defined above) -#define constant ENTRY_BYTES = 0x04 // each entry in the lookup table is 4 bytes -#define constant ENTRY_MASK = 0xFFFFFFFF // mask used to cast bytes32 -> lookup table entry -#define table SIN_LUT { - 0x00000000000000000000000000000000000000000000000000000000000001000000000000c90f8801921d20025b26d703242abf03ed26e604b6195d057f00350647d97c0710a34507d95b9e08a2009a096a90490a3308bc0afb68050bc3ac350c8bd35e0d53db920e1bc2e40ee387660fab272b1072a0481139f0cf120116d512c8106e138edbb1145576b1151bdf8515e2144416a81305176dd9de183366e818f8b83c19bdcbf31a82a0251b4732ef1c0b826a1ccf8cb31d934fe51e56ca1e1f19f97b1fdcdc1b209f701c2161b39f2223a4c522e541af23a6887e2467775725280c5d25e845b626a8218527679df42826b92828e5714a29a3c4852a61b1012b1f34eb2bdc4e6f2c98fbba2d553afb2e110a622ecc681e2f8752623041c76030fbc54d31b54a5d326e54c73326e2c233def2873496824f354d905636041ad936ba2013376f9e46382493b038d8fe93398cdd323a402dd13af2eeb73ba51e293c56ba703d07c1d53db832a53e680b2c3f1749b73fc5ec974073f21d4121589a41ce1e64427a41d04325c13543d09aec447acd50452456bc45cd358f46756827471cece647c3c22e4869e664490f57ee49b415334a581c9d4afb6c974b9e038f4c3fdff34ce100344d8162c34e2106174ebfe8a44f5e08e24ffb654c5097fc5e5133cc9451ced46e5269126e53028517539b2aef5433027d54ca0a4a556040e255f5a4d2568a34a9571deef957b0d2555842dd5458d40e8c5964649759f3de125a8279995b1035ce5b9d11535c290acc5cb420df5d3e52365dc79d7b5e50015d5ed77c895f5e0db25fe3b38d60686cce60ec382f616f146b61f1003e6271fa6862f201ac637114cc63ef328f646c59bf64e889256563bf9165ddfbd266573cbb66cf811f6746c7d767bd0fbc683257aa68a69e806919e31f698c246b69fd614a6a6d98a36adcc9646b4af2786bb812d06c24295f6c8f351b6cf934fb6d6227f96dca0d146e30e3496e96a99c6efb5f116f5f02b16fc1938470231099708378fe70e2cbc571410804719e2cd171fa394872552c8472af05a67307c3cf735f662573b5ebd0740b53fa745f9dd074b2c8837504d3447555bd4b75a585ce75f42c0a7641af3c768e0ea576d9498877235f2c776c4eda77b417df77fab988784033287884841378c7aba17909a92c794a7c11798a23b079c89f6d7a05eeac7a4210d87a7d055a7ab6cba37aef63237b26cb4e7b5d039d7b920b887bc5e28f7bf8882f7c29fbed7c5a3d4f7c894bdd7cb727237ce3ceb17d0f42177d3980eb7d628ac57d8a5f3f7db0fdf77dd6668e7dfa98a77e1d93e97e3f57fe7e5fe4927e7f39567e9d55fb7eba3a387ed5e5c57ef0585f7f0991c37f2191b37f3857f57f4de4507f62368e7f754e7f7f872bf27f97cebc7fa736b37fb563b27fc255957fce0c3d7fd8878d7fe1c76a7fe9cbbf7ff094777ff621817ffa72d07ffd88597fff62157fffffff -} - -#define constant WAD = 0x0de0b6b3a7640000 -#define constant I32_MAX = 0x7fffffff - -//////////////////////////////////////////////////////////////// -// BASIC TRIG // -//////////////////////////////////////////////////////////////// - -/// @notice Return the sine of a value, specified in radians scaled by 1e18 -/// @dev This algorithm for converting sine only uses integer values, and it works by dividing the -/// circle into 30 bit angles, i.e. there are 1,073,741,824 (2^30) angle units, instead of the -/// standard 360 degrees (2pi radians). From there, we get an output in range -2,147,483,647 to -/// 2,147,483,647, (which is the max value of an int32) which is then converted back to the standard -/// range of -1 to 1, again scaled by 1e18 -/// @param _angle Angle to convert -/// @return Result scaled by 1e18 -#define macro SIN() = takes (1) returns (1) { - // Input stack: [angle] - - // Convert angle from from arbitrary radian value (range of 0 to 2pi) to the algorithm's range - // of 0 to 1,073,741,824 - [TWO_PI] dup1 // [TWO_PI, TWO_PI, angle] - swap2 // [angle, TWO_PI, TWO_PI] - mod // [angle % TWO_PI, TWO_PI] - [ANGLES_IN_CYCLE] mul // [ANGLES_IN_CYCLE * (angle % TWO_PI), TWO_PI] - div // [ANGLES_IN_CYCLE * (angle % TWO_PI) / TWO_PI] - // [angle] - - // Apply a mask on an integer to extract a certain number of bits, where angle is the integer - // whose bits we want to get, the width is the width of the bits (in bits) we want to extract, - // and the offset is the offset of the bits (in bits) we want to extract. The result is an - // integer containing _width bits of _value starting at the offset bit - dup1 // [angle, angle] - [INTERP_OFFSET] shr // [angle >> INTERP_OFFSET, angle] - 0x01 dup1 // [0x01, 0x01, angle >> INTERP_OFFSET, angle] - [INTERP_WIDTH] shl // [0x01 << INTERP_WIDTH, 0x01, angle >> INTERP_OFFSET, angle] - sub // [(0x01 << INTERP_WIDTH) - 0x01, angle >> INTERP_OFFSET, angle] - and // [interp, angle] - - dup2 // [angle, interp, angle] - [INDEX_OFFSET] shr // [angle >> INDEX_OFFSET, interp, angle] - 0x01 dup1 // [0x01, 0x01, angle >> INDEX_OFFSET, interp, angle] - [INDEX_WIDTH] shl // [0x01 << INDEX_WIDTH, 0x01, angle >> INDEX_OFFSET, interp, angle] - sub // [(0x01 << INDEX_WIDTH) - 0x01, angle >> INDEX_OFFSET, interp, angle] - and // [index, interp, angle] - - // The lookup table only contains data for one quadrant (since sin is symmetric around both - // axes), so here we figure out which quadrant we're in, then we lookup the values in the - // table then modify values accordingly - dup3 // [angle, index, interp, angle] - [QUADRANT_LOW_MASK] // [QUADRANT_LOW_MASK, angle, index, interp, angle] - and // [QUADRANT_LOW_MASK & angle, index, interp, angle] - iszero // [is_odd_quadrant, index, interp, angle] - - dup4 // [angle, is_odd_quadrant, index, interp, angle] - [QUADRANT_HIGH_MASK] // [QUADRANT_HIGH_MASK, angle, is_odd_quadrant, index, interp, angle] - and // [QUADRANT_HIGH_MASK & angle, is_odd_quadrant, index, interp, angle] - iszero iszero // [is_negative_quadrant, is_odd_quadrant, index, interp, angle] - - // Jump past updating the index if `is_odd_quadrant` is true - dup2 is_odd_q jumpi // [is_negative_quadrant, is_odd_quadrant, index, interp, angle] - - dup3 // [index, is_negative_quadrant, is_odd_quadrant, index, interp, angle] - 0x01 // [0x01, index, is_negative_quadrant, is_odd_quadrant, index, interp, angle] - [SINE_TABLE_SIZE] // [SINE_TABLE_SIZE, 0x01, index, is_negative_quadrant, is_odd_quadrant, index, interp, angle] - sub sub // [SINE_TABLE_SIZE - 0x01 - index, is_negative_quadrant, is_odd_quadrant, index, interp, angle] - swap3 pop // [is_negative_quadrant, is_odd_quadrant, index, interp, angle] - - is_odd_q: - - // We are looking for two consecutive indices in our lookup table - // Since EVM is left aligned, to read n bytes of data from idx i, we must read from `i * data_len` + `n` - // therefore, to read two entries of size entry_bytes `index * entry_bytes` + `entry_bytes * 2` - swap2 // [index, is_odd_quadrant, is_negative_quadrant, interp, angle] - 0x02 add // [index + 0x02, is_odd_quadrant, is_negative_quadrant, interp, angle] - [ENTRY_BYTES] mul // [offset1_2, is_odd_quadrant, is_negative_quadrant, interp, angle] - - // This following snippet will function for any entry_bytes <= 15 - __tablestart(SIN_LUT) // [sin_table_start, offset1_2, is_odd_quadrant, is_negative_quadrant, interp, angle] - add // [sin_table_start + offset1_2, is_odd_quadrant, is_negative_quadrant, interp, angle] - 0x20 swap1 // [sin_table_start + offset1_2, 0x20, is_odd_quadrant, is_negative_quadrant, interp, angle] - 0x00 codecopy // [is_odd_quadrant, is_negative_quadrant, interp, angle] - - 0x00 mload // [x1_2, is_odd_quadrant, is_negative_quadrant, interp, angle] - - // We now read the last two numbers of size entry_bytes from x1_2 - // in example: entry_bytes = 4; x1_2 = 0x00...12345678abcdefgh - // therefore: entry_mask = 0xFFFFFFFF - - // 0x00...12345678abcdefgh >> 8*4 = 0x00...12345678 - // 0x00...12345678 & 0xFFFFFFFF = 0x12345678 - dup1 0x20 shr // [x1_2 >> 0x20, x1_2, is_odd_quadrant, is_negative_quadrant, interp, angle] - [ENTRY_MASK] and // [x1, x1_2, is_odd_quadrant, is_negative_quadrant, interp, angle] - - // 0x00...12345678abcdefgh & 0xFFFFFFFF = 0xabcdefgh - swap1 [ENTRY_MASK] // [ENTRY_MASK, x1_2, x1, is_odd_quadrant, is_negative_quadrant, interp, angle] - and // [x2, x1, is_odd_quadrant, is_negative_quadrant, interp, angle] - - // Approximate angle by interpolating in the table, accounting for the quadrant - dup2 dup2 sub // [x2 - x1, x2, x1, is_odd_quadrant, is_negative_quadrant, interp, angle] - dup6 mul // [interp * (x2 - x1), x2, x1, is_odd_quadrant, is_negative_quadrant, interp, angle] - [INTERP_WIDTH] shr // [(interp * (x2 - x1)) >> INTERP_WIDTH, x2, x1, is_odd_quadrant, is_negative_quadrant, interp, angle] - - swap3 // [is_odd_quadrant, x2, x1, (interp * (x2 - x1)) >> INTERP_WIDTH, is_negative_quadrant, interp, angle] - is_odd jumpi // [x2, x1, (interp * (x2 - x1)) >> INTERP_WIDTH, is_negative_quadrant, interp, angle] - - is_even: - swap1 pop // [x2, (interp * (x2 - x1)) >> INTERP_WIDTH, is_negative_quadrant, interp, angle] - sub // [x2 - (interp * (x2 - x1)) >> INTERP_WIDTH, is_negative_quadrant, interp, angle] - finish jump - is_odd: - pop add // [x1 + (interp * (x2 - x1)) >> INTERP_WIDTH, is_negative_quadrant, interp, angle] - finish: - // Received stack: [sine, is_negative_quadrant, interp, angle] - swap1 // [is_negative_quadrant, sine, interp, angle] - iszero cont jumpi // [sine, interp, angle] - - // Negative 1 - 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF - mul // [-sine, interp, angle] - - cont: - // Bring result from the range of -2,147,483,647 through 2,147,483,647 to -1e18 through 1e18. - // This can never overflow because sine is bounded by the above values - [WAD] mul // [1e18 * sine, interp, angle] - [I32_MAX] // [I32_MAX, 1e18 * sine, interp, angle] - swap1 sdiv // [1e18 * sine / I32_MAX, interp, angle] - - // Clean stack: - swap2 pop pop // [1e18 * sine / I32_MAX] - - // Return stack: [1e18 * sine / I32_MAX] -} - -/// @notice Return the cosine of a value, specified in radians scaled by 1e18 -/// @dev This is identical to the sin() method, and just computes the value by delegating to the -/// sin() method using the identity cos(x) = sin(x + pi/2) -/// @dev Overflow when `angle + PI_OVER_TWO > type(uint256).max` is ok, results are still accurate -/// @param _angle Angle to convert -/// @return Result scaled by 1e18 -#define macro COS() = takes (1) returns (1) { - // Input stack: [angle] - - [PI_OVER_TWO] add // [angle + pi/2] - SIN() // [result] - - // Return stack: [result] -} \ No newline at end of file diff --git a/src/math/__TEMP__qakkodxedbspprhymlfrgxlfepgepcrvTrigonometry.huff b/src/math/__TEMP__qakkodxedbspprhymlfrgxlfepgepcrvTrigonometry.huff deleted file mode 100644 index a74aa9a7..00000000 --- a/src/math/__TEMP__qakkodxedbspprhymlfrgxlfepgepcrvTrigonometry.huff +++ /dev/null @@ -1,218 +0,0 @@ -#define function sin(uint256) pure returns (int256) -#define function cos(uint256) pure returns (int256) - -#define macro SIN_WRAPPER() = takes (0) returns (0) { - 0x04 calldataload // [angle] - SIN() // [sin(angle)] - 0x00 mstore // [] - 0x20 0x00 return -} - -#define macro COS_WRAPPER() = takes (0) returns (0) { - 0x04 calldataload // [angle] - COS() // [cos(angle)] - 0x00 mstore // [] - 0x20 0x00 return -} - -#define macro MAIN() = takes (0) returns (0) { - pc calldataload 0xE0 shr - dup1 __FUNC_SIG(sin) eq sin jumpi - dup1 __FUNC_SIG(cos) eq cos jumpi - - 0x00 dup1 revert - - sin: - SIN_WRAPPER() - cos: - COS_WRAPPER() -} - -/// @title Trigonometry -/// @notice SPDX-License-Identifier: MIT -/// @author mds1 -/// @author clabby -/// @notice Basic trigonometry functions where inputs and outputs are integers. -/// Inputs are specified in radians scaled by 1e18, and similarly outputs are scaled by 1e18. -/// @notice Adapted from mds1 (https://github.com/mds1/solidity-trigonometry/blob/main/src/Trigonometry.sol) - -//////////////////////////////////////////////////////////////// -// CONSTANTS // -//////////////////////////////////////////////////////////////// - -// Table index into the trigonometric table -#define constant INDEX_WIDTH = 0x08 - -// Interpolation between successive entries in the table -#define constant INTERP_WIDTH = 0x10 -#define constant INDEX_OFFSET = 0x14 -#define constant INTERP_OFFSET = 0x04 -#define constant ANGLES_IN_CYCLE = 0x40000000 -#define constant QUADRANT_HIGH_MASK = 0x20000000 -#define constant QUADRANT_LOW_MASK = 0x10000000 -#define constant SINE_TABLE_SIZE = 0x100 - -// Pi as an 18 decimal value, which is plenty of accuracy: "For JPL's highest accuracy calculations, which are for -// interplanetary navigation, we use 3.141592653589793: https://www.jpl.nasa.gov/edu/news/2016/3/16/how-many-decimals-of-pi-do-we-really-need/ -#define constant PI = 0x2B992DDFA23249D6 -#define constant TWO_PI = 0x57325BBF446493AC -#define constant PI_OVER_TWO = 0x15CC96EFD1192500 - -// The constant sine lookup table was generated by generate_trigonometry.py. We must use a constant -// bytes array because constant arrays are not supported in Solidity. Each entry in the lookup -// table is 4 bytes. Since we're using 32-bit parameters for the lookup table, we get a table size -// of 2^(32/4) + 1 = 257, where the first and last entries are equivalent (hence the table size of -// 256 defined above) -#define constant ENTRY_BYTES = 0x04 // each entry in the lookup table is 4 bytes -#define constant ENTRY_MASK = 0xFFFFFFFF // mask used to cast bytes32 -> lookup table entry -#define table SIN_LUT { - 0x00000000000000000000000000000000000000000000000000000000000001000000000000c90f8801921d20025b26d703242abf03ed26e604b6195d057f00350647d97c0710a34507d95b9e08a2009a096a90490a3308bc0afb68050bc3ac350c8bd35e0d53db920e1bc2e40ee387660fab272b1072a0481139f0cf120116d512c8106e138edbb1145576b1151bdf8515e2144416a81305176dd9de183366e818f8b83c19bdcbf31a82a0251b4732ef1c0b826a1ccf8cb31d934fe51e56ca1e1f19f97b1fdcdc1b209f701c2161b39f2223a4c522e541af23a6887e2467775725280c5d25e845b626a8218527679df42826b92828e5714a29a3c4852a61b1012b1f34eb2bdc4e6f2c98fbba2d553afb2e110a622ecc681e2f8752623041c76030fbc54d31b54a5d326e54c73326e2c233def2873496824f354d905636041ad936ba2013376f9e46382493b038d8fe93398cdd323a402dd13af2eeb73ba51e293c56ba703d07c1d53db832a53e680b2c3f1749b73fc5ec974073f21d4121589a41ce1e64427a41d04325c13543d09aec447acd50452456bc45cd358f46756827471cece647c3c22e4869e664490f57ee49b415334a581c9d4afb6c974b9e038f4c3fdff34ce100344d8162c34e2106174ebfe8a44f5e08e24ffb654c5097fc5e5133cc9451ced46e5269126e53028517539b2aef5433027d54ca0a4a556040e255f5a4d2568a34a9571deef957b0d2555842dd5458d40e8c5964649759f3de125a8279995b1035ce5b9d11535c290acc5cb420df5d3e52365dc79d7b5e50015d5ed77c895f5e0db25fe3b38d60686cce60ec382f616f146b61f1003e6271fa6862f201ac637114cc63ef328f646c59bf64e889256563bf9165ddfbd266573cbb66cf811f6746c7d767bd0fbc683257aa68a69e806919e31f698c246b69fd614a6a6d98a36adcc9646b4af2786bb812d06c24295f6c8f351b6cf934fb6d6227f96dca0d146e30e3496e96a99c6efb5f116f5f02b16fc1938470231099708378fe70e2cbc571410804719e2cd171fa394872552c8472af05a67307c3cf735f662573b5ebd0740b53fa745f9dd074b2c8837504d3447555bd4b75a585ce75f42c0a7641af3c768e0ea576d9498877235f2c776c4eda77b417df77fab988784033287884841378c7aba17909a92c794a7c11798a23b079c89f6d7a05eeac7a4210d87a7d055a7ab6cba37aef63237b26cb4e7b5d039d7b920b887bc5e28f7bf8882f7c29fbed7c5a3d4f7c894bdd7cb727237ce3ceb17d0f42177d3980eb7d628ac57d8a5f3f7db0fdf77dd6668e7dfa98a77e1d93e97e3f57fe7e5fe4927e7f39567e9d55fb7eba3a387ed5e5c57ef0585f7f0991c37f2191b37f3857f57f4de4507f62368e7f754e7f7f872bf27f97cebc7fa736b37fb563b27fc255957fce0c3d7fd8878d7fe1c76a7fe9cbbf7ff094777ff621817ffa72d07ffd88597fff62157fffffff -} - -#define constant WAD = 0x0de0b6b3a7640000 -#define constant I32_MAX = 0x7fffffff - -//////////////////////////////////////////////////////////////// -// BASIC TRIG // -//////////////////////////////////////////////////////////////// - -/// @notice Return the sine of a value, specified in radians scaled by 1e18 -/// @dev This algorithm for converting sine only uses integer values, and it works by dividing the -/// circle into 30 bit angles, i.e. there are 1,073,741,824 (2^30) angle units, instead of the -/// standard 360 degrees (2pi radians). From there, we get an output in range -2,147,483,647 to -/// 2,147,483,647, (which is the max value of an int32) which is then converted back to the standard -/// range of -1 to 1, again scaled by 1e18 -/// @param _angle Angle to convert -/// @return Result scaled by 1e18 -#define macro SIN() = takes (1) returns (1) { - // Input stack: [angle] - - // Convert angle from from arbitrary radian value (range of 0 to 2pi) to the algorithm's range - // of 0 to 1,073,741,824 - [TWO_PI] dup1 // [TWO_PI, TWO_PI, angle] - swap2 // [angle, TWO_PI, TWO_PI] - mod // [angle % TWO_PI, TWO_PI] - [ANGLES_IN_CYCLE] mul // [ANGLES_IN_CYCLE * (angle % TWO_PI), TWO_PI] - div // [ANGLES_IN_CYCLE * (angle % TWO_PI) / TWO_PI] - // [angle] - - // Apply a mask on an integer to extract a certain number of bits, where angle is the integer - // whose bits we want to get, the width is the width of the bits (in bits) we want to extract, - // and the offset is the offset of the bits (in bits) we want to extract. The result is an - // integer containing _width bits of _value starting at the offset bit - dup1 // [angle, angle] - [INTERP_OFFSET] shr // [angle >> INTERP_OFFSET, angle] - 0x01 dup1 // [0x01, 0x01, angle >> INTERP_OFFSET, angle] - [INTERP_WIDTH] shl // [0x01 << INTERP_WIDTH, 0x01, angle >> INTERP_OFFSET, angle] - sub // [(0x01 << INTERP_WIDTH) - 0x01, angle >> INTERP_OFFSET, angle] - and // [interp, angle] - - dup2 // [angle, interp, angle] - [INDEX_OFFSET] shr // [angle >> INDEX_OFFSET, interp, angle] - 0x01 dup1 // [0x01, 0x01, angle >> INDEX_OFFSET, interp, angle] - [INDEX_WIDTH] shl // [0x01 << INDEX_WIDTH, 0x01, angle >> INDEX_OFFSET, interp, angle] - sub // [(0x01 << INDEX_WIDTH) - 0x01, angle >> INDEX_OFFSET, interp, angle] - and // [index, interp, angle] - - // The lookup table only contains data for one quadrant (since sin is symmetric around both - // axes), so here we figure out which quadrant we're in, then we lookup the values in the - // table then modify values accordingly - dup3 // [angle, index, interp, angle] - [QUADRANT_LOW_MASK] // [QUADRANT_LOW_MASK, angle, index, interp, angle] - and // [QUADRANT_LOW_MASK & angle, index, interp, angle] - iszero // [is_odd_quadrant, index, interp, angle] - - dup4 // [angle, is_odd_quadrant, index, interp, angle] - [QUADRANT_HIGH_MASK] // [QUADRANT_HIGH_MASK, angle, is_odd_quadrant, index, interp, angle] - and // [QUADRANT_HIGH_MASK & angle, is_odd_quadrant, index, interp, angle] - iszero iszero // [is_negative_quadrant, is_odd_quadrant, index, interp, angle] - - // Jump past updating the index if `is_odd_quadrant` is true - dup2 is_odd_q jumpi // [is_negative_quadrant, is_odd_quadrant, index, interp, angle] - - dup3 // [index, is_negative_quadrant, is_odd_quadrant, index, interp, angle] - 0x01 // [0x01, index, is_negative_quadrant, is_odd_quadrant, index, interp, angle] - [SINE_TABLE_SIZE] // [SINE_TABLE_SIZE, 0x01, index, is_negative_quadrant, is_odd_quadrant, index, interp, angle] - sub sub // [SINE_TABLE_SIZE - 0x01 - index, is_negative_quadrant, is_odd_quadrant, index, interp, angle] - swap3 pop // [is_negative_quadrant, is_odd_quadrant, index, interp, angle] - - is_odd_q: - - // We are looking for two consecutive indices in our lookup table - // Since EVM is left aligned, to read n bytes of data from idx i, we must read from `i * data_len` + `n` - // therefore, to read two entries of size entry_bytes `index * entry_bytes` + `entry_bytes * 2` - swap2 // [index, is_odd_quadrant, is_negative_quadrant, interp, angle] - 0x02 add // [index + 0x02, is_odd_quadrant, is_negative_quadrant, interp, angle] - [ENTRY_BYTES] mul // [offset1_2, is_odd_quadrant, is_negative_quadrant, interp, angle] - - // This following snippet will function for any entry_bytes <= 15 - __tablestart(SIN_LUT) // [sin_table_start, offset1_2, is_odd_quadrant, is_negative_quadrant, interp, angle] - add // [sin_table_start + offset1_2, is_odd_quadrant, is_negative_quadrant, interp, angle] - 0x20 swap1 // [sin_table_start + offset1_2, 0x20, is_odd_quadrant, is_negative_quadrant, interp, angle] - 0x00 codecopy // [is_odd_quadrant, is_negative_quadrant, interp, angle] - - 0x00 mload // [x1_2, is_odd_quadrant, is_negative_quadrant, interp, angle] - - // We now read the last two numbers of size entry_bytes from x1_2 - // in example: entry_bytes = 4; x1_2 = 0x00...12345678abcdefgh - // therefore: entry_mask = 0xFFFFFFFF - - // 0x00...12345678abcdefgh >> 8*4 = 0x00...12345678 - // 0x00...12345678 & 0xFFFFFFFF = 0x12345678 - dup1 0x20 shr // [x1_2 >> 0x20, x1_2, is_odd_quadrant, is_negative_quadrant, interp, angle] - [ENTRY_MASK] and // [x1, x1_2, is_odd_quadrant, is_negative_quadrant, interp, angle] - - // 0x00...12345678abcdefgh & 0xFFFFFFFF = 0xabcdefgh - swap1 [ENTRY_MASK] // [ENTRY_MASK, x1_2, x1, is_odd_quadrant, is_negative_quadrant, interp, angle] - and // [x2, x1, is_odd_quadrant, is_negative_quadrant, interp, angle] - - // Approximate angle by interpolating in the table, accounting for the quadrant - dup2 dup2 sub // [x2 - x1, x2, x1, is_odd_quadrant, is_negative_quadrant, interp, angle] - dup6 mul // [interp * (x2 - x1), x2, x1, is_odd_quadrant, is_negative_quadrant, interp, angle] - [INTERP_WIDTH] shr // [(interp * (x2 - x1)) >> INTERP_WIDTH, x2, x1, is_odd_quadrant, is_negative_quadrant, interp, angle] - - swap3 // [is_odd_quadrant, x2, x1, (interp * (x2 - x1)) >> INTERP_WIDTH, is_negative_quadrant, interp, angle] - is_odd jumpi // [x2, x1, (interp * (x2 - x1)) >> INTERP_WIDTH, is_negative_quadrant, interp, angle] - - is_even: - swap1 pop // [x2, (interp * (x2 - x1)) >> INTERP_WIDTH, is_negative_quadrant, interp, angle] - sub // [x2 - (interp * (x2 - x1)) >> INTERP_WIDTH, is_negative_quadrant, interp, angle] - finish jump - is_odd: - pop add // [x1 + (interp * (x2 - x1)) >> INTERP_WIDTH, is_negative_quadrant, interp, angle] - finish: - // Received stack: [sine, is_negative_quadrant, interp, angle] - swap1 // [is_negative_quadrant, sine, interp, angle] - iszero cont jumpi // [sine, interp, angle] - - // Negative 1 - 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF - mul // [-sine, interp, angle] - - cont: - // Bring result from the range of -2,147,483,647 through 2,147,483,647 to -1e18 through 1e18. - // This can never overflow because sine is bounded by the above values - [WAD] mul // [1e18 * sine, interp, angle] - [I32_MAX] // [I32_MAX, 1e18 * sine, interp, angle] - swap1 sdiv // [1e18 * sine / I32_MAX, interp, angle] - - // Clean stack: - swap2 pop pop // [1e18 * sine / I32_MAX] - - // Return stack: [1e18 * sine / I32_MAX] -} - -/// @notice Return the cosine of a value, specified in radians scaled by 1e18 -/// @dev This is identical to the sin() method, and just computes the value by delegating to the -/// sin() method using the identity cos(x) = sin(x + pi/2) -/// @dev Overflow when `angle + PI_OVER_TWO > type(uint256).max` is ok, results are still accurate -/// @param _angle Angle to convert -/// @return Result scaled by 1e18 -#define macro COS() = takes (1) returns (1) { - // Input stack: [angle] - - [PI_OVER_TWO] add // [angle + pi/2] - SIN() // [result] - - // Return stack: [result] -} \ No newline at end of file diff --git a/src/math/__TEMP__qnnyckotyuxpdpeuvffbywnubcftdxsyFixedPointMath.huff b/src/math/__TEMP__qnnyckotyuxpdpeuvffbywnubcftdxsyFixedPointMath.huff deleted file mode 100644 index 323bcc19..00000000 --- a/src/math/__TEMP__qnnyckotyuxpdpeuvffbywnubcftdxsyFixedPointMath.huff +++ /dev/null @@ -1,1093 +0,0 @@ -#define function mulDivDown(uint256,uint256,uint256) pure returns(uint256) -#define function mulDivUp(uint256,uint256,uint256) pure returns(uint256) -#define function mulWadDown(uint256,uint256) pure returns(uint256) -#define function mulWadUp(uint256,uint256) pure returns(uint256) -#define function divWadDown(uint256,uint256) pure returns(uint256) -#define function divWadUp(uint256,uint256) pure returns(uint256) -#define function rpow(uint256,uint256,uint256) pure returns(uint256) -#define function expWad(int256) pure returns(int256) -#define function powWad(int256,int256) pure returns(int256) -#define function lnWad(int256) pure returns(int256) -#define function sqrt(uint256) pure returns(uint256) -#define function log2(uint256) pure returns(uint256) -#define function cbrt(uint256) pure returns(uint256) - -#define macro MUL_DIV_DOWN_WRAPPER(fail) = takes (0) returns (0) { - 0x44 calldataload // [denominator] - 0x24 calldataload // [y, denominator] - 0x04 calldataload // [x, y, denominator] - MUL_DIV_DOWN(fail) // [result] - 0x00 mstore // [] - 0x20 0x00 return -} - -#define macro MUL_DIV_UP_WRAPPER(fail) = takes (0) returns (0) { - 0x44 calldataload // [denominator] - 0x24 calldataload // [y, denominator] - 0x04 calldataload // [x, y, denominator] - MUL_DIV_UP(fail) // [result] - 0x00 mstore // [] - 0x20 0x00 return -} - -#define macro MUL_WAD_DOWN_WRAPPER(fail) = takes (0) returns (0) { - 0x24 calldataload // [y] - 0x04 calldataload // [x, y] - MUL_WAD_DOWN(fail) // [result] - 0x00 mstore // [] - 0x20 0x00 return -} - -#define macro MUL_WAD_UP_WRAPPER(fail) = takes (0) returns (0) { - 0x24 calldataload // [y] - 0x04 calldataload // [x, y] - MUL_WAD_UP(fail) // [result] - 0x00 mstore // [] - 0x20 0x00 return -} - -#define macro DIV_WAD_DOWN_WRAPPER(fail) = takes (0) returns (0) { - 0x24 calldataload // [y] - 0x04 calldataload // [x, y] - DIV_WAD_DOWN(fail) // [result] - 0x00 mstore // [] - 0x20 0x00 return -} - -#define macro DIV_WAD_UP_WRAPPER(fail) = takes (0) returns (0) { - 0x24 calldataload // [y] - 0x04 calldataload // [x, y] - DIV_WAD_UP(fail) // [result] - 0x00 mstore // [] - 0x20 0x00 return -} - -#define macro RPOW_WRAPPER(fail) = takes (0) returns (0) { - 0x44 calldataload // [scalar] - 0x24 calldataload // [n, scalar] - 0x04 calldataload // [x, n, scalar] - RPOW(fail) // [result] - 0x00 mstore // [] - 0x20 0x00 return -} - -#define macro EXP_WAD_WRAPPER(fail) = takes (0) returns (0) { - 0x04 calldataload // [x] - EXP_WAD(fail) // [result] - 0x00 mstore - 0x20 0x00 return -} - -#define macro LN_WAD_WRAPPER(fail) = takes (0) returns (0) { - 0x04 calldataload // [x] - LN_WAD(fail) // [result] - 0x00 mstore - 0x20 0x00 return -} - -#define macro POW_WAD_WRAPPER(fail) = takes (0) returns (0) { - 0x24 calldataload // [y] - 0x04 calldataload // [x, y] - POW_WAD(fail) // [result] - 0x00 mstore // [] - 0x20 0x00 return -} - -#define macro SQRT_WRAPPER() = takes (0) returns (0) { - 0x04 calldataload // [x] - SQRT() // [result] - 0x00 mstore - 0x20 0x00 return -} - -#define macro LOG_2_WRAPPER(fail) = takes (0) returns (0) { - 0x04 calldataload // [x] - LOG_2(fail) // [result] - 0x00 mstore - 0x20 0x00 return -} - -#define macro CBRT_WRAPPER() = takes (0) returns (0) { - 0x04 calldataload - CBRT() - 0x00 mstore - 0x20 0x00 return -} - -#define macro MAIN() = takes (0) returns (0) { - pc calldataload 0xE0 shr - dup1 __FUNC_SIG(mulDivDown) eq mulDivDown jumpi - dup1 __FUNC_SIG(mulDivUp) eq mulDivUp jumpi - dup1 __FUNC_SIG(mulWadDown) eq mulWadDown jumpi - dup1 __FUNC_SIG(mulWadUp) eq mulWadUp jumpi - dup1 __FUNC_SIG(divWadDown) eq divWadDown jumpi - dup1 __FUNC_SIG(divWadUp) eq divWadUp jumpi - dup1 __FUNC_SIG(rpow) eq rpow jumpi - dup1 __FUNC_SIG(expWad) eq expWad jumpi - dup1 __FUNC_SIG(lnWad) eq lnWad jumpi - dup1 __FUNC_SIG(powWad) eq powWad jumpi - dup1 __FUNC_SIG(sqrt) eq sqrt jumpi - dup1 __FUNC_SIG(log2) eq logTwo jumpi - dup1 __FUNC_SIG(cbrt) eq cbrt jumpi - - - fail: - 0x00 0x00 revert - mulDivDown: - MUL_DIV_DOWN_WRAPPER(fail) - mulDivUp: - MUL_DIV_UP_WRAPPER(fail) - mulWadDown: - MUL_WAD_DOWN_WRAPPER(fail) - mulWadUp: - MUL_WAD_UP_WRAPPER(fail) - divWadDown: - DIV_WAD_DOWN_WRAPPER(fail) - divWadUp: - DIV_WAD_UP_WRAPPER(fail) - rpow: - RPOW_WRAPPER(fail) - expWad: - EXP_WAD_WRAPPER(fail) - lnWad: - LN_WAD_WRAPPER(fail) - powWad: - POW_WAD_WRAPPER(fail) - sqrt: - SQRT_WRAPPER() - logTwo: - LOG_2_WRAPPER(fail) - cbrt: - CBRT_WRAPPER() -} - -/// @title FixedPointMath -/// @notice SPDX-License-Identifier: MIT -/// @author clabby -/// @notice Minimal module for fixed-point number arithmetic -/// @notice Adapted from Solmate (https://github.com/transmissions11/solmate/blob/v7/src/utils/FixedPointMathLib.sol) - -#define constant WAD = 0x0de0b6b3a7640000 -#define constant DAY = 0x15180 - -//////////////////////////////////////////////////////////////// -// SIMPLIFIED FIXED POINT OPERATIONS // -//////////////////////////////////////////////////////////////// - -// https://github.com/transmissions11/solmate/blob/v7/src/utils/FixedPointMathLib.sol#L13 -#define macro MUL_WAD_DOWN(fail) = takes (2) returns (1) { - // Input stack: [x, y] - [WAD] // [WAD, x, y] - ARRANGE_STACK_MULWAD() // [x, y, WAD] - MUL_DIV_DOWN(fail) // [result] -} - -// https://github.com/transmissions11/solmate/blob/v7/src/utils/FixedPointMathLib.sol#L17 -#define macro MUL_WAD_UP(fail) = takes (2) returns (1) { - // Input stack: [x, y] - [WAD] // [WAD, x, y] - ARRANGE_STACK_MULWAD() // [x, y, WAD] - MUL_DIV_UP(fail) // [result] -} - -// https://github.com/transmissions11/solmate/blob/v7/src/utils/FixedPointMathLib.sol#L21 -#define macro DIV_WAD_DOWN(fail) = takes (2) returns (1) { - // Input stack: [x, y] - [WAD] // [WAD, x, y] - ARRANGE_STACK_DIVWAD() // [x, WAD, y] - MUL_DIV_DOWN(fail) -} - -// https://github.com/transmissions11/solmate/blob/v7/src/utils/FixedPointMathLib.sol#L25 -#define macro DIV_WAD_UP(fail) = takes (2) returns (1) { - // Input stack: [x, y] - [WAD] // [WAD, x, y] - ARRANGE_STACK_DIVWAD() // [x, WAD, y] - MUL_DIV_UP(fail) // [result] -} - -// https://github.com/transmissions11/solmate/blob/v7/src/utils/FixedPointMathLib.sol#L34 -#define macro EXP_WAD(fail) = takes (1) returns (1) { - // Input stack: [x] - - // When the result is < 0.5 we return zero. This happens when - // x <= floor(log(0.5e18) * 1e18) ~ -42e18 - 0xfffffffffffffffffffffffffffffffffffffffffffffffdb731c958f34d94c1 - dup2 // [x, 0xfff..., x] - sgt iszero // [x <= 0xfff..., x] - ret_zero jumpi // [x] - - // When the result is > (2**255 - 1) / 1e18 we can not represent it as an - // int. This happens when x >= floor(log((2**255 - 1) / 1e18) * 1e18) ~ 135. - 0x0755bf798b4a1bf1e5 // [0x0755bf798b4a1bf1e5, x] - dup2 // [x, 0x0755bf798b4a1bf1e5, x] - slt iszero // [x >= 0x0755bf798b4a1bf1e5, x] - jumpi // [x] - - // x is now in the range (-42, 136) * 1e18. Convert to (-42, 136) * 2**96 - // for more intermediate precision and a binary basis. This base conversion - // is a multiplication by 1e18 / 2**96 = 5**18 / 2**78. - 0x03782dace9d9 // [0x05 ** 0x12, x] - swap1 // [x, 0x05 ** 0x12] - 0x4e shl // [x << 0x4e, 0x05 ** 0x12] - sdiv // [x << 0x4e / 0x05 ** 0x12] - - // Reduce range of x to (-1/2 ln 2, 1/2 ln 2) * 2**96 by factoring out powers - // of two such that exp(x) = exp(x') * 2**k, where k is an integer. - // Solving this gives k = round(x / log(2)) and x' = x - k * log(2). - 0xb17217f7d1cf79abc9e3b398 - dup2 // [x, 0xb17217f7d1cf79abc9e3b398, x] - 0x60 shl // [x << 96, 0xb17217f7d1cf79abc9e3b398, x] - sdiv // [x << 96 / 0xb17217f7d1cf79abc9e3b398, x] - 0x7ffffff20f9306d2eea00000 // [2**95, x << 96 / 0xb17217f7d1cf79abc9e3b398, x] - add // [2**95 + x << 96 / 0xb17217f7d1cf79abc9e3b398, x] - 0x60 sar // [(2**95 + x << 96 / 0xb17217f7d1cf79abc9e3b398) >> 96, x] - - dup1 // [(2**95 + x << 96 / 0xb17217f7d1cf79abc9e3b398) >> 96, (2**95 + x << 96 / 0xb17217f7d1cf79abc9e3b398) >> 96, x] - 0xb17217f7d1cf79abc9e3b398 - mul // [((2**95 + x << 96 / 0xb17217f7d1cf79abc9e3b398) >> 96) * 0xb17217f7d1cf79abc9e3b398, (2**95 + x << 96 / 0xb17217f7d1cf79abc9e3b398) >> 96, x] - dup3 // [x, ((2**95 + x << 96 / 0xb17217f7d1cf79abc9e3b398) >> 96) * 0xb17217f7d1cf79abc9e3b398, (2**95 + x << 96 / 0xb17217f7d1cf79abc9e3b398) >> 96, x] - sub // [x (new), (2**95 + x << 96 / 0xb17217f7d1cf79abc9e3b398) >> 96, x] - swap2 pop // [k, x] - - // k is in the range [-61, 195]. - - // Evaluate using a (6, 7)-term rational approximation. - // p is made monic, we'll multiply by a scale factor later. - 0x10fe68e7fd37d0007b713f7650 - dup3 // [x, 0x10fe68e7fd37d0007b713f7650, k, x] - add // [y, k, x] - - 0x02d16720577bd19bf614176fe9ea - dup2 dup5 mul // [x * y, 0x02d16720577bd19bf614176fe9ea, y, k, x] - 0x60 sar // [(x * y) >> 0x60, 0x02d16720577bd19bf614176fe9ea, y, k, x] - add // [((x * y) >> 0x60) + 0x02d16720577bd19bf614176fe9ea, y, k, x] - swap1 pop // [y, k, x] - - 0x04a4fd9f2a8b96949216d2255a6c - dup4 dup3 add // [x + y, 0x04a4fd9f2a8b96949216d2255a6c, y, k, x] - sub // [x + y - 0x04a4fd9f2a8b96949216d2255a6c, y, k, x] - - dup2 // [y, x + y - 0x04a4fd9f2a8b96949216d2255a6c, y, k, x] - mul // [y * (x + y - 0x04a4fd9f2a8b96949216d2255a6c), y, k, x] - 0x60 sar // [(y * (x + y - 0x04a4fd9f2a8b96949216d2255a6c)) >> 0x60, y, k, x] - 0x0587f503bb6ea29d25fcb740196450 - add // [p, y, k, x] - - dup4 // [x, p, y, k, x] - mul // [x * p, y, k, x] - 0xd835ebba824c98fb31b83b2ca45c - 0x60 shl // [0xd835ebba824c98fb31b83b2ca45c << 0x60, x * p, y, k, x] - add // [p, y, k, x] - - // We leave p in 2**192 basis so we don't need to scale it back up for the division. - - 0x240c330e9fb2d9cbaf0fd5aafc - dup5 sub // [q, p, y, k, x] - - dup5 mul // [x * q, p, y, k, x] - 0x60 sar // [(x * q) >> 0x60, p, y, k, x] - 0x0277594991cfc85f6e2461837cd9 - add // [q, p, y, k, x] - - dup5 mul // [x * q, p, y, k, x] - 0x60 sar // [(x * q) >> 0x60, p, y, k, x] - 0x1a521255e34f6a5061b25ef1c9c4 swap1 - sub // [q, p, y, k, x] - - dup5 mul // [x * q, p, y, k, x] - 0x60 sar // [(x * q) >> 0x60, p, y, k, x] - 0xb1bbb201f443cf962f1a1d3db4a5 - add // [q, p, y, k, x] - - dup5 mul // [x * q, p, y, k, x] - 0x60 sar // [(x * q) >> 0x60, p, y, k, x] - 0x02c72388d9f74f51a9331fed693f15 swap1 - sub // [q, p, y, k, x] - - dup5 mul // [x * q, p, y, k, x] - 0x60 sar // [(x * q) >> 0x60, p, y, k, x] - 0x05180bb14799ab47a8a8cb2a527d57 - add // [q, p, y, k, x] - - // The q polynomial won't have zeros in the domain as all its roots are complex. - // No scaling is necessary because p is already 2**96 too large. - swap1 sdiv // [p / q (r), y, k, x] - - // r should be in the range (0.09, 0.25) * 2**96. - - // We now need to multiply r by: - // * the scale factor s = ~6.031367120. - // * the 2**k factor from the range reduction. - // * the 1e18 / 2**96 factor for base conversion. - // We do this all at once, with an intermediate result in 2**213 - // basis, so the final right shift is always by a positive amount. - - 0x029d9dc38563c32e5c2f6dc192ee70ef65f9978af3 - mul // [0x029d9... * r, y, k, x] - dup3 // [k, 0x029d9... * r, y, k, x] - 0xc3 sub // [0xc3 - k, 0x029d9... * r, y, k, x] - shr // [(0x029d9... * r) >> 0xc3 - k, y, k, x] - - // Clean stack - swap3 pop pop pop // [result] - - finish jump - - ret_zero: - 0x00 dup1 mstore - 0x20 0x00 return - finish: - // Return stack: [result] -} - -// https://github.com/transmissions11/solmate/blob/v7/src/utils/FixedPointMathLib.sol#L92 -#define macro LN_WAD(fail) = takes (1) returns (1) { - // Input stack: [x] - 0x00 dup2 sgt // [x > 0, x] - iszero // [x <= 0, x] - jumpi // [x] - - // We want to convert x from 10**18 fixed point to 2**96 fixed point. - // We do this by multiplying by 2**96 / 10**18. But since - // ln(x * C) = ln(x) + ln(C), we can simply do nothing here - // and add ln(2**96 / 10**18) at the end. - - // Reduce range of x to (1, 2) * 2**96 - // ln(2^k * x) = k * ln(2) + ln(x) - 0x60 // [0x60, x] - dup2 LOG_2(fail) // [log2(x), 0x60, x] - sub // [k, x] - - dup2 dup2 // [k, x, k, x] - 0x9f sub // [0x9f - k, x, k, x] - shl // [x << (0x9f - k), k, x] - 0x9f shr // [x_new, k, x] - swap2 pop // [k, x] - - // Evaluate using a (8, 8)-term rational approximation. - // p is made monic, we will multiply by a scale factor later. - dup2 // [x, k, x] - 0x29508e458543d8aa4df2abee78 - add // [p, k, x] - - dup3 mul // [p * x, k, x] - 0x60 sar // [(p * x) >> 0x60, k, x] - 0x0139601a2efabe717e604cbb4894 - add // [p, k, x] - - dup3 mul // [p * x, k, x] - 0x60 sar // [(p * x) >> 0x60, k, x] - 0x02247f7a7b6594320649aa03aba1 - add // [p, k, x] - - 0x8c3f38e95a6b1ff2ab1c3b3437 - swap1 dup4 mul // [p * x, 0x8c3f..., k, x] - 0x60 sar // [(p * x) >> 0x60, 0x8c3f..., k, x] - sub // [p, k, x] - - 0x02384773bdf1ac5676facced6091 - swap1 dup4 mul // [p * x, 0x0238..., k, x] - 0x60 sar // [(p * x) >> 0x60, 0x0238..., k, x] - sub // [p, k, x] - - 0xb9a025d814b29c212b8b1a07ce - swap1 dup4 mul // [p * x, 0xb9a0..., k, x] - 0x60 sar // [(p * x) >> 0x60, 0xb9a0..., k, x] - sub // [p, k, x] - - 0x0a09507084cc699bb0e71ea86a - 0x60 shl // [0x0a09... << 0x60, p, k, x] - swap1 // [p, 0x0a09... << 0x60, k, x] - dup4 mul // [p * x, 0x0a09... << 0x60, k, x] - sub // [p, k, x] - - // We leave p in 2**192 basis so we don't need to scale it back up for the division. - // q is monic by convention. - dup3 // [x, p, k, x] - 0x465772b2bbbb5f824b15207a30 - add // [q, p, k, x] - - dup4 mul // [q * x, p, k, x] - 0x60 sar // [(q * x) >> 0x60, p, k, x] - 0x0388eaa27412d5aca026815d636e - add // [q, p, k, x] - - dup4 mul // [q * x, p, k, x] - 0x60 sar // [(q * x) >> 0x60, p, k, x] - 0x0df99ac502031bf953eff472fdcc - add // [q, p, k, x] - - dup4 mul // [q * x, p, k, x] - 0x60 sar // [(q * x) >> 0x60, p, k, x] - 0x13cdffb29d51d99322bdff5f2211 - add // [q, p, k, x] - - dup4 mul // [q * x, p, k, x] - 0x60 shr // [(q * x) >> 0x60, p, k, x] - 0x0a0f742023def783a307a986912e - add // [q, p, k, x] - - dup4 mul // [q * x, p, k, x] - 0x60 sar // [(q * x) >> 0x60, p, k, x] - 0x01920d8043ca89b5239253284e42 - add // [q, p, k, x] - - dup4 mul // [q * x, p, k, x] - 0x60 sar // [(q * x) >> 0x60, p, k, x] - 0x0b7a86d7375468fac667a0a527 - add // [q, p, k, x] - - // The q polynomial is known not to have zeros in the domain. - // No scaling required because p is already 2**96 too large. - swap1 sdiv // [p / q (r), k, x] - - // r is in the range (0, 0.125) * 2**96 - - // Finalization, we need to: - // * multiply by the scale factor s = 5.549... - // * add ln(2**96 / 10**18) - // * add k * ln(2) - // * multiply by 10**18 / 2**96 = 5**18 >> 78 - - // mul s * 5e18 * 2**96, base is now 5**18 * 2**192 - 0x1340daa0d5f769dba1915cef59f0815a5506 mul - - // add ln(2) * k * 5e18 * 2**192 - swap1 // [k, r, x] - 0x0267a36c0c95b3975ab3ee5b203a7614a3f75373f047d803ae7b6687f2b3 - mul // [k * 0x0267..., r, x] - add // [r, x] - - // add ln(2**96 / 10**18) * 5e18 * 2**192 - 0x57115e47018c7177eebf7cd370a3356a1b7863008a5ae8028c72b8864284 - add // [r, x] - - // base conversion: mul 2**18 / 2**192 - 0xAE sar // [r >> 0xAE, x] - - finish jump - - finish: - // Clean stack - swap1 pop - // Return stack: [result] -} - -// https://github.com/transmissions11/solmate/blob/v7/src/utils/FixedPointMathLib.sol#L29 -#define macro POW_WAD(fail) = takes (2) returns (1) { - // Input Stack: [x, y] - LN_WAD(fail) // [lnWad(x), y] - mul // [lnWad(x) * y] - [WAD] swap1 // [lnWad(x) * y, 1e18] - sdiv // [(lnWad(x) * y) / 1e18] - EXP_WAD(fail) // [result] -} - -//////////////////////////////////////////////////////////////// -// LOW LEVEL FIXED POINT OPERATIONS // -//////////////////////////////////////////////////////////////// - -// https://github.com/transmissions11/solmate/blob/main/src/utils/FixedPointMathLib.sol#L34 -#define macro MUL_DIV_DOWN(fail) = takes (3) returns (1) { - // Input stack: [x, y, denominator] - dup1 dup3 mul // [x * y, x, y, denominator] - dup1 // [x * y, x * y, x, y, denominator] - swap2 dup1 // [x, x, x * y, x * y, y, denominator] - - iszero // [x == 0, x, x * y, x * y, y, denominator] - swap2 // [x * y, x, x == 0, x * y, y, denominator] - div // [(x * y) / x, x == 0, x * y, y, denominator] - dup4 eq // [y == (x * y) / x, x == 0, x * y, y, denominator] - or // [y == (x * y) / x | x == 0, x * y, y, denominator] - swap2 pop // [x * y, y == (x * y) / x | x == 0, denominator] - swap1 dup3 // [denominator, y == (x * y) / x | x == 0, x * y, denominator] - iszero iszero // [denominator != 0, y == (x * y) / x | x == 0, x * y, denominator] - and // [denominator != 0 & y == (x * y) / x | x == 0, x * y, denominator] - - iszero jumpi // [x * y, denominator] - - div // [(x * y) / denominator] - // Return stack: [(x * y) / denominator] -} - -// https://github.com/transmissions11/solmate/blob/main/src/utils/FixedPointMathLib.sol#L53 -#define macro MUL_DIV_UP(fail) = takes (3) returns (1) { - // Input stack: [x, y, denominator] - dup1 dup3 mul // [x * y, x, y, denominator] - dup1 // [x * y, x * y, x, y, denominator] - swap2 dup1 // [x, x, x * y, x * y, y, denominator] - - iszero // [x == 0, x, x * y, x * y, y, denominator] - swap2 // [x * y, x, x == 0, x * y, y, denominator] - div // [(x * y) / x, x == 0, x * y, y, denominator] - dup4 eq // [y == (x * y) / x, x == 0, x * y, y, denominator] - or // [y == (x * y) / x | x == 0, x * y, y, denominator] - swap2 pop // [x * y, y == (x * y) / x | x == 0, denominator] - swap1 dup3 // [denominator, y == (x * y) / x | x == 0, x * y, denominator] - iszero iszero // [denominator != 0, y == (x * y) / x | x == 0, x * y, denominator] - and // [denominator != 0 & y == (x * y) / x | x == 0, x * y, denominator] - - iszero jumpi // [x * y, denominator] - - dup1 // [x * y, x * y, denominator] - iszero iszero // [x * y != 0, x * y, denominator] - - dup3 // [denominator, x * y != 0, x * y, denominator] - 0x01 // [1, denominator, x * y != 0, x * y, denominator] - dup4 // [x * y, 1, denominator, x * y != 0, x * y, denominator] - sub // [x * y - 1, denominator, x * y != 0, x * y, denominator] - div // [x * y - 1 / denominator, x * y != 0, x * y, denominator] - 0x01 // [1, x * y - 1 / denominator, x * y != 0, x * y, denominator] - add // [(x * y - 1 / denominator) + 1, x * y != 0, x * y, denominator] - - mul // [((x * y - 1 / denominator) + 1) * (x * y != 0), x * y, denominator] - - // Clear extra stack items before continuing - swap2 // [denominator, x * y, ((x * y - 1 / denominator) + 1) * (x * y != 0)] - pop pop // [((x * y - 1 / denominator) + 1) * (x * y != 0)] - // Return stack: [((x * y - 1 / denominator) + 1) * (x * y != 0)] -} - -// https://github.com/transmissions11/solmate/blob/main/src/utils/FixedPointMathLib.sol#L74 -// TODO: Optimize, works but not great -#define macro RPOW(fail) = takes (3) returns (1) { - // Input stack: [x, n, scalar] - dup1 // [x, x, n, scalar] - default jumpi // Jump to "default" if x != 0 - - // TODO: Fix hack- code following `finish` label pops four items off of - // the stack, so we fill it with extra items here in order to return - // the scalar or 0. - - dup3 dup4 // [scalar, scalar, x, n, scalar] - dup4 iszero // [n == 0, scalar, scalar, x, n, scalar] - finish jumpi // If n == 0 && x == 0, return the scalar (0 ** 0 = 1). - - // 0 ** n = 0 - 0x00 dup1 finish jump // Finish execution - - default: - dup3 // [scalar, x, n, scalar] - 0x01 shr // [scalar >> 1, x, n, scalar] - - dup4 // [result, scalar >> 1, x, n, scalar] - 0x02 // [2, result, scalar >> 1, x, n, scalar] - dup5 // [n, 2, result, scalar >> 1, x, n, scalar] - mod // [n % 2, result, scalar >> 1, x, n, scalar] - - // Set result to scalar for now if n % 2 is even - iszero loop jumpi // [result, scalar >> 1, x, n, scalar]] - - // Set result to x for now if n % 2 is odd - pop dup2 // [result, scalar >> 1, x, n, scalar] - loop: - dup4 // [n, result, scalar >> 1, x, n, scalar] - iszero finish jumpi // If n == 0, the loop is finished. - - // Divide n by 2 - dup4 // [n, result, scalar >> 1, x, n, scalar] - 0x01 shr // [n >> 1, result, scalar >> 1, x, n, scalar] - swap4 pop // [result, scalar >> 1, x, n, scalar] - - // Revert if x ** 2 will overflow. - dup3 // [x, result, scalar >> 1, x, n, scalar] - 0x80 shr // [x >> 128, result, scalar >> 1, x, n, scalar] - - // Square x and duplicate it on the stack for use later. - dup4 // [x, x >> 128, result, scalar >> 1, x, n, scalar] - dup1 mul // [x * x, x >> 128, result, scalar >> 1, x, n, scalar] - dup1 // [x * x, x * x, x >> 128, result, scalar >> 1, x, n, scalar] - - // Add x ** 2 to scalar >> 1 - dup5 // [scalar >> 1, x * x, x * x, x >> 128, result, scalar >> 1, x, n, scalar] - add // [(scalar >> 1) + (x * x), x * x, x >> 128, result, scalar >> 1, x, n, scalar] - - // Revert if x ** 2 + scalar >> 1 overflowed - swap2 // [x >> 128, x * x, (scalar >> 1) + (x * x), result, scalar >> 1, x, n, scalar] - swap1 // [x * x, x >> 128, (scalar >> 1) + (x * x), result, scalar >> 1, x, n, scalar] - dup3 lt // [(scalar >> 1) + (x * x) < x * x, x >> 128, (scalar >> 1) + (x * x), result, scalar >> 1, x, n, scalar] - or jumpi // [(scalar >> 1) + (x * x), result, scalar >> 1, x, n, scalar] - - // Set x to ((scalar >> 1) + (x * x)) / scalar - dup6 // [scalar, (scalar >> 1) + (x * x), result, scalar >> 1, x, n, scalar] - swap1 // [(scalar >> 1) + (x * x), scalar, result, scalar >> 1, x, n, scalar] - div // [((scalar >> 1) + (x * x)) / scalar, result, scalar >> 1, x, n, scalar] - swap3 pop // [result, scalar >> 1, x, n, scalar] - - 0x02 // [2, result, scalar >> 1, x, n, scalar] - dup5 // [n, 2, result, scalar >> 1, x, n, scalar] - mod // [n % 2, result, scalar >> 1, x, n, scalar] - - // If n is even, continue loop - iszero loop jumpi - // If n is odd, continue logic - - // Multiply x * result - dup1 // [result, result, scalar >> 1, x, n, scalar] - dup4 // [x, result, result, scalar >> 1, x, n, scalar] - mul // [x * result, result, scalar >> 1, x, n, scalar] - dup1 // [x * result, x * result, result, scalar >> 1, x, n, scalar] - dup1 // [x * result, x * result, x * result, result, scalar >> 1, x, n, scalar] - - // Check if x * result overflowed - dup6 // [x, x * result, x * result, x * result, result, scalar >> 1, x, n, scalar] - swap1 // [x * result, x, x * result, x * result, result, scalar >> 1, x, n, scalar] - div // [x * result / x, x * result, x * result, result, scalar >> 1, x, n, scalar] - dup4 // [result, x * result / x, x * result, x * result, result, scalar >> 1, x, n, scalar] - eq iszero // [result != (x * result / x), x * result, x * result, result, scalar >> 1, x, n, scalar] - dup6 // [x, result != (x * result / x), x * result, x * result, result, scalar >> 1, x, n, scalar] - iszero iszero // [x != 0, result != (x * result / x), x * result, x * result, result, scalar >> 1, x, n, scalar] - and // [x != 0 & result != (x * result / x), x * result, x * result, result, scalar >> 1, x, n, scalar] - swap2 // [x * result, x * result, x != 0 & result != (x * result / x), result, scalar >> 1, x, n, scalar] - - // Round to the nearest number - dup5 // [scalar >> 1, x * result, x * result, x != 0 & result != (x * result / x), result, scalar >> 1, x, n, scalar] - add // [(scalar >> 1) + (x * result), x * result, x != 0 & result != (x * result / x), result, scalar >> 1, x, n, scalar] - - // Check if x ** 2 + scalar >> 1 overflowed - swap2 // [x != 0 & result != (x * result / x), x * result, (scalar >> 1) + (x * result), result, scalar >> 1, x, n, scalar] - swap1 // [x * result, x != 0 & result != (x * result / x), (scalar >> 1) + (x * result), result, scalar >> 1, x, n, scalar] - dup3 lt // [(scalar >> 1) + (x * result) < x * result, x != 0 & result != (x * result / x), (scalar >> 1) + (x * result), result, scalar >> 1, x, n, scalar] - - // Revert if ((scalar >> 1) + (x * result)) < x * result OR x != 0 & result != (x * result / x) - or jumpi // [(scalar >> 1) + (x * result), result, scalar >> 1, x, n, scalar] - - // Scale rounded result - dup6 // [scalar, (scalar >> 1) + (x * result), result, scalar >> 1, x, n, scalar] - swap1 // [(scalar >> 1) + (x * result), scalar, result, scalar >> 1, x, n, scalar] - div // [(scalar >> 1) + (x * result)) / scalar, result, scalar >> 1, x, n, scalar] - swap1 pop // [result, scalar >> 1, x, n, scalar] - - loop jump // Continue loop - // Return result - finish: - // Clean Stack - swap4 // [scalar, scalar >> 1, x, n, result] - pop pop pop pop // [result] - // Return stack: [result] -} - -//////////////////////////////////////////////////////////////// -// GENERAL NUMBER UTILITIES // -//////////////////////////////////////////////////////////////// - -// https://github.com/transmissions11/solmate/blob/v7/src/utils/FixedPointMathLib.sol#L288 -#define macro SQRT() = takes (1) returns (1) { - // Input stack: [x] - - // We start y at x, which will help us make our initial estimate. - dup1 // [y, x] - - // The "correct" value is 1, but this saves a multiplication later. - 0xb5 // [0xb5, y, x] - - 0x10000000000000000000000000000000000 - dup3 // [y, 0x1000..., z, y, x] - lt // [y < 0x1000..., z, y, x] - continue_1 jumpi // [z, y, x] - - 0x40 shl // [z << 0x40, y, x] - swap1 // [y, z << 0x40, x] - 0x80 shr // [y >> 0x80, z << 0x40, x] - swap1 // [z << 0x40, y >> 0x80, x] - - continue_1: - - 0x1000000000000000000 - dup3 // [y, 0x1000..., z, y, x] - lt // [y < 0x1000..., z, y, x] - continue_2 jumpi // [z, y, x] - - 0x20 shl // [z << 0x20, y, x] - swap1 // [y, z << 0x20, x] - 0x40 shr // [y >> 0x40, z << 0x20, x] - swap1 // [z << 0x20, y >> 0x40, x] - - continue_2: - - 0x10000000000 - dup3 // [y, 0x1000..., z, y, x] - lt // [y < 0x1000..., z, y, x] - continue_3 jumpi // [z, y, x] - - 0x10 shl // [z << 0x10, y, x] - swap1 // [y, z << 0x10, x] - 0x20 shr // [y >> 0x20, z << 0x10, x] - swap1 // [z << 0x10, y >> 0x20, x] - - continue_3: - - 0x1000000 - dup3 // [y, 0x1000..., z, y, x] - lt // [y < 0x1000..., z, y, x] - continue_4 jumpi // [z, y, x] - - 0x08 shl // [z << 0x08, y, x] - swap1 // [y, z << 0x08, x] - 0x10 shr // [y >> 0x10, z << 0x08, x] - swap1 // [z << 0x08, y >> 0x10, x] - - continue_4: - - // Goal was to get z*z*y within a small factor of x. More iterations could - // get y in a tighter range. Currently, we will have y in [256, 256*2^16). - // We ensured y >= 256 so that the relative difference between y and y+1 is small. - // That's not possible if x < 256 but we can just verify those cases exhaustively. - - // Now, z*z*y <= x < z*z*(y+1), and y <= 2^(16+8), and either y >= 256, or x < 256. - // Correctness can be checked exhaustively for x < 256, so we assume y >= 256. - // Then z*sqrt(y) is within sqrt(257)/sqrt(256) of sqrt(x), or about 20bps. - - // For s in the range [1/256, 256], the estimate f(s) = (181/1024) * (s+1) is in the range - // (1/2.84 * sqrt(s), 2.84 * sqrt(s)), with largest error when s = 1 and when s = 256 or 1/256. - - // Since y is in [256, 256*2^16), let a = y/65536, so that a is in [1/256, 256). Then we can estimate - // sqrt(y) using sqrt(65536) * 181/1024 * (a + 1) = 181/4 * (y + 65536)/65536 = 181 * (y + 65536)/2^18. - - // There is no overflow risk here since y < 2^136 after the first branch above. - - // A mul is saved from starting z at 181. - swap1 // [y, z, x] - 0x010000 add // [y + 0x010000, z, x] - mul // [(y + 0x010000) * z, x] - 0x12 shr // [((y + 0x010000) * z) >> 0x12, x] - - // Given the worst case multiplicative error of 2.84 above, 7 iterations should be enough. - dup1 dup3 // [x, z, z, x] - div // [x / z, z, x] - add // [x / z + z, x] - 0x01 shr // [(x / z + z) >> 0x01, x] - - dup1 dup3 // [x, z, z, x] - div // [x / z, z, x] - add // [x / z + z, x] - 0x01 shr // [(x / z + z) >> 0x01, x] - - dup1 dup3 // [x, z, z, x] - div // [x / z, z, x] - add // [x / z + z, x] - 0x01 shr // [(x / z + z) >> 0x01, x] - - dup1 dup3 // [x, z, z, x] - div // [x / z, z, x] - add // [x / z + z, x] - 0x01 shr // [(x / z + z) >> 0x01, x] - - dup1 dup3 // [x, z, z, x] - div // [x / z, z, x] - add // [x / z + z, x] - 0x01 shr // [(x / z + z) >> 0x01, x] - - dup1 dup3 // [x, z, z, x] - div // [x / z, z, x] - add // [x / z + z, x] - 0x01 shr // [(x / z + z) >> 0x01, x] - - dup1 dup3 // [x, z, z, x] - div // [x / z, z, x] - add // [x / z + z, x] - 0x01 shr // [(x / z + z) >> 0x01, x] - - // If x+1 is a perfect square, the Babylonian method cycles between - // floor(sqrt(x)) and ceil(sqrt(x)). This statement ensures we return floor. - // See: https://en.wikipedia.org/wiki/Integer_square_root#Using_only_integer_division - // Since the ceil is rare, we save gas on the assignment and repeat division in the rare case. - // If you don't care whether the floor or ceil square root is returned, you can remove this statement. - dup1 dup1 swap3 // [x, z, z, z] - div // [x / z, z, z] - lt // [(x / z) < z, z] - swap1 sub // [z - (x / z) < z] -} - -// https://github.com/transmissions11/solmate/blob/v7/src/utils/FixedPointMathLib.sol#L352 -#define macro LOG_2(fail) = takes (1) returns (1) { - // Input stack: [x] - - dup1 iszero // [x == 0, x] - jumpi // [x] - - dup1 // [x, x] - 0xffffffffffffffffffffffffffffffff - lt // [0xffff... < x, x] - 0x07 shl // [r, x] - - dup2 dup2 // [r, x, r, x] - shr // [x >> r, r, x] - 0xffffffffffffffff lt // [0xffff... < (x >> r), r, x] - 0x06 shl // [(0xffff... < (x >> r)) << 6, r, x] - or // [r | (0xffff... < (x >> r)) << 6, x] - - dup2 dup2 // [r, x, r, x] - shr // [x >> r, r, x] - 0xffffffff lt // [0xffff... < (x >> r), r, x] - 0x05 shl // [(0xffff... < (x >> r)) << 5, r, x] - or // [r | (0xffff... < (x >> r)) << 5, x] - - dup2 dup2 // [r, x, r, x] - shr // [x >> r, r, x] - 0xffff lt // [0xffff < (x >> r), r, x] - 0x04 shl // [(0xffff < (x >> r)) << 4, r, x] - or // [r | (0xffff < (x >> r)) << 4, x] - - dup2 dup2 // [r, x, r, x] - shr // [x >> r, r, x] - 0xff lt // [0xff < (x >> r), r, x] - 0x03 shl // [(0xff < (x >> r)) << 3, r, x] - or // [r | (0xff < (x >> r)) << 3, x] - - dup2 dup2 // [r, x, r, x] - shr // [x >> r, r, x] - 0x0f lt // [0x0f < (x >> r), r, x] - 0x02 shl // [(0x0f < (x >> r)) << 2, r, x] - or // [r | (0x0f < (x >> r)) << 2, x] - - dup2 dup2 // [r, x, r, x] - shr // [x >> r, r, x] - 0x03 lt // [0x03 < (x >> r), r, x] - 0x01 shl // [(0x03 < (x >> r)) << 1, r, x] - or // [r | (0x03 < (x >> r)) << 1, x] - - dup2 dup2 // [r, x, r, x] - shr // [x >> r, r, x] - 0x01 lt // [0x01 < (x >> r), r, x] - or // [r, x] - swap1 pop // [r] - - // Return stack: // [result] -} - -/// @notice Calculates the cube root of the stack input -/// Credits: https://github.com/Vectorized/solady/blob/main/src/utils/FixedPointMathLib.sol#L504 -#define macro CBRT() = takes (1) returns (1) { - // Input Stack: [x] - - // r construction - - dup1 // [x, x] - 0xffffffffffffffffffffffffffffffff // [0xffffffffffffffffffffffffffffffff, x, x] - lt // [0xffffffffffffffffffffffffffffffff< x, x] - 0x7 shl // [0xffffffffffffffffffffffffffffffff < x << 7, x] - // r = 0xffffffffffffffffffffffffffffffff < x << 7 - - dup2 dup2 // [r, x, r, x] - shr // [x >> r, r, x] - 0xffffffffffffffff // [0xffffffffffffffff, x >> r, r, x] - lt // [0xffffffffffffffff < x >> r, r, x] - 0x6 shl // [0xffffffffffffffff < x >> r << 6, r, x] - or // [0xffffffffffffffff < x >> r << 6 | r, x] - // r' = r | (0xffffffffffffffff < (x >> r)) << 6 - - dup2 dup2 // [r', x, r', x] - shr // [x >> r', r', x] - 0xffffffff // [0xffffffff, x >> r', r', x] - lt // [0xffffffff < x >> r, r', x] - 0x5 shl // [0xffffffff < x >> r << 5, r', x] - or // [0xffffffff < x >> r << 5 | r', x] - // r' = r' | 0xffffffff < x >> r << 5 - - dup2 dup2 // [r', x, r', x] - shr // [x >> r', r', x] - 0xffff // [0xffff, x >> r', r',x] - lt // [0xffff < x >> r', r', x] - 0x4 shl // [0xffff < x >> r' << 4, r', x] - or // [0xffff < x >> r' << 4 | r', x] - // r' = r' | 0xffff < x >> r' << 4 - - dup2 dup2 // [r', x, r', x] - shr // [x >> r', r', x] - 0xff // [0xff, x >> r', r', x] - lt // [0xff < x >> r', r', x] - 0x3 shl // [0xff < x >> r' << 3, r', x] - or // [0xff < x >> r' << 3 | r', x] - // r' = r'|0xff < x >> r' << 3 - - // z construction - - 0xff // [0xff, r', x] - dup3 dup3 // [r', x, 0xff, r', x] - shr // [x >> r', 0xff, r', x] - 0xf // [0xf, x >> r', 0xff, r', x] - lt // [0xf < x >> r', 0xff, r', x] - 0x3 // [3, 0xf < x >> r', 0xff, r', x] - dup4 // [r', 3, 0xf < x >> r', 0xff, r', x] - div // [r' / 3, 0xf < x >> r', 0xff, r', x] - add // [r' / 3 + 0xf < x >> r', 0xff, r', x] - shl // [0xff << r' / 3 + 0xf < x >> r', r', x] - // z = 0xff << r' / 3 + 0xf < x >> r' - - 0x3 // [0x3, z, r', x] - swap1 // [z, 0x3, r', x] - swap2 // [r', 0x3, z, x] - mod // [r' % 3, z, x] - 0x7f624b // [0x7f624b, r' % 3, z, x] - 0xe8 // [0xe8, 0x7f624b, r' % 3, z, x] - shl // [0x7f624b << 0xe8, r' % 3, z, x] - swap1 // [r' % 3, 0x7f624b << 0xe8, z, x] - byte // [byte(r' % 3, 0x7f624b << 0xe8), z, x] - swap1 // [z, byte(r' % 3, 0x7f624b << 0xe8), x] - div // [z / byte(r' % 3, 0x7f624b << 0xe8), x] - // z' = z / byte(r' % 3, 0xe8 << 0x7f624b) - - // Round 1 / 7 - 0x3 // [3, z', x] - swap1 dup1 // [z', z', 3, x] - dup1 dup1 // [z', z', z', z', 3, x] - mul // [z' * z', z', z', 3, x] - dup5 // [x, z' * z', z', z', 3, x] - div add // [x / z' * z' + z', z', 3, x] - add div // [((x / (z' * z')) + z') + z') / 3, x] - // z' = ((x / (z' * z'))+ z') + z') / 3 - - // Round 2 / 7 - 0x3 // [3, z', x] - swap1 dup1 // [z', z', 3, x] - dup1 dup1 // [z', z', z', z', 3, x] - mul // [z' * z', z', z', 3, x] - dup5 // [x, z' * z', z', z', 3, x] - div add // [x / z' * z' + z', z', 3, x] - add div // [((x / (z' * z'))+ z') + z') / 3, x] - // z' = ((x / (z' * z'))+ z') + z') / 3 - - // Round 3 / 7 - 0x3 // [3, z', x] - swap1 dup1 // [z', z', 3, x] - dup1 dup1 // [z', z', z', z', 3, x] - mul // [z' * z', z', z', 3, x] - dup5 // [x, z' * z', z', z', 3, x] - div add // [x / z' * z' + z', z', 3, x] - add div // [((x / (z' * z'))+ z') + z') / 3, x] - // z' = ((x / (z' * z'))+ z') + z') / 3 - - // Round 4 / 7 - 0x3 // [3, z', x] - swap1 dup1 // [z', z', 3, x] - dup1 dup1 // [z', z', z', z', 3, x] - mul // [z' * z', z', z', 3, x] - dup5 // [x, z' * z', z', z', 3, x] - div add // [x / z' * z' + z', z', 3, x] - add div // [((x / (z' * z'))+ z') + z') / 3, x] - // z' = ((x / (z' * z'))+ z') + z') / 3 - - // Round 5 / 7 - 0x3 // [3, z', x] - swap1 dup1 // [z', z', 3, x] - dup1 dup1 // [z', z', z', z', 3, x] - mul // [z' * z', z', z', 3, x] - dup5 // [x, z' * z', z', z', 3, x] - div add // [x / z' * z' + z', z', 3, x] - add div // [((x / (z' * z'))+ z') + z') / 3, x] - // z' = ((x / (z' * z'))+ z') + z') / 3 - - // Round 6 / 7 - 0x3 // [3, z', x] - swap1 dup1 // [z', z', 3, x] - dup1 dup1 // [z', z', z', z', 3, x] - mul // [z' * z', z', z', 3, x] - dup5 // [x, z' * z', z', z', 3, x] - div add // [x / z' * z' + z', z', 3, x] - add div // [((x / (z' * z'))+ z') + z') / 3, x] - // z' = ((x / (z' * z'))+ z') + z') / 3 - - // Round 7 / 7 - 0x3 // [3, z', x] - swap1 dup1 // [z', z', 3, x] - dup1 dup1 // [z', z', z', z', 3, x] - mul // [z' * z', z', z', 3, x] - dup5 // [x, z' * z', z', z', 3, x] - div add // [x / z' * z' + z', z', 3, x] - add div // [((x / (z' * z'))+ z') + z') / 3, x] - // z' = ((x / (z' * z'))+ z') + z') / 3 - - // Final operation - dup1 swap2 // [x, z', z'] - dup2 dup1 // [z', z', x, z', z'] - mul // [z' * z', x, z', z'] - swap1 // [x, z' * z', z', z'] - div // [x / (z' * z'), z', z'] - lt // [x / (z' * z') < z', z'] - swap1 sub // [z' - (x / (z' * z') < z')] - - // Return stack: [result: z'] -} - -//////////////////////////////////////////////////////////////// -// HELPER MACROS // -//////////////////////////////////////////////////////////////// - -#define macro ARRANGE_STACK_MULWAD() = takes (3) returns (3) { - // Input stack: [WAD, x, y] - swap2 // [y, x, WAD] - swap1 // [x, y, WAD] -} - -#define macro ARRANGE_STACK_DIVWAD() = takes (3) returns (3) { - // Input stack: [WAD, x, y] - swap1 // [x, WAD, y] -} - -// TESTS - -#define macro TEST_ASSERT_EQ() = { - eq continue jumpi - 0x00 dup1 revert - continue: -} - -// test wad mul for positive numbers -#define test TEST_WAD_DIV() = { - 0xDE0B6B3A7640000 // [y (1e18)] - 0x1BC16D674EC80000 // [x (2e18),y] - WAD_MUL(fail) // result - 0x1BC16D674EC80000 - TEST_ASSERT_EQ() - continue jump - - fail: - FAIL() - continue: -} - -// test wad mul for positive numbers -#define test TEST_WAD_MUL() = { - 0x0DE0B6B3A7640000 // [y (1e18)] - 0x1BC16D674EC80000 // [x (2e18), y] - WAD_MUL(fail) // result - - 0x1BC16D674EC80000 - TEST_ASSERT_EQ() - continue jump - // catch jump label - fail: - 0x00 dup1 revert - continue: -} - -#define test FAIL_WAD_MUL() = { - 0xF0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF - 0x20 - WAD_MUL(fail) - 0x00 dup1 revert - - // succeed if fails - fail: -} - -#define test FAIL_WAD_DIV() = { - 0x00 - 0x0DE0B6B3A7640000 - WAD_DIV(fail) - 0x00 dup1 revert - - // succeed if fails - fail: -} - - -#define test TEST_TO_WAD_UNSAFE() = { - // Test 0x2 * WAD = 2e18 - 0x02 - TO_WAD_UNSAFE() - 0x1BC16D674EC80000 // [2*e18] - TEST_ASSERT_EQ() -} diff --git a/src/math/__TEMP__qvmazraiuhrdvuoecpapxakdrzpwpmuqMath.huff b/src/math/__TEMP__qvmazraiuhrdvuoecpapxakdrzpwpmuqMath.huff deleted file mode 100644 index 1c65a83e..00000000 --- a/src/math/__TEMP__qvmazraiuhrdvuoecpapxakdrzpwpmuqMath.huff +++ /dev/null @@ -1,319 +0,0 @@ - -#define macro SQRT_WRAPPER() = { - 0x04 calldataload - SQRT() - 0x00 mstore - 0x20 0x00 return -} - -#define macro MAX_WRAPPER() = { - 0x04 calldataload - 0x24 calldataload - MAX() - 0x00 mstore - 0x20 0x00 return -} - -#define macro MIN_WRAPPER() = { - 0x04 calldataload - 0x24 calldataload - MIN() - 0x00 mstore - 0x20 0x00 return -} - -#define macro AVG_WRAPPER() = { - 0x04 calldataload - 0x24 calldataload - AVG() - 0x00 mstore - 0x20 0x00 return -} - -#define macro CEIL_DIV_WRAPPER() = { - 0x24 calldataload - 0x04 calldataload - CEIL_DIV() - 0x00 mstore - 0x20 0x00 return -} - -#define macro MAIN() = { - 0x00 calldataload 0xE0 shr - dup1 __FUNC_SIG(sqrt) eq sqrt jumpi - dup1 __FUNC_SIG(max) eq max jumpi - dup1 __FUNC_SIG(min) eq min jumpi - dup1 __FUNC_SIG(average) eq average jumpi - dup1 __FUNC_SIG(ceilDiv) eq ceilDiv jumpi - - 0x00 0x00 revert - - sqrt: - SQRT_WRAPPER() - max: - MAX_WRAPPER() - min: - MIN_WRAPPER() - average: - AVG_WRAPPER() - ceilDiv: - CEIL_DIV_WRAPPER() -} - - -/// @title Math -/// @notice SPDX-License-Identifier: MIT -/// @author manas -/// @author kadenzipfel -/// @notice Math module over Solidity's arithmetic operations -/// @notice Adapted from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/math/Math.sol) - -#include "../utils/Errors.huff" - -// Interface -#define function sqrt(uint256) pure returns(uint256) -#define function max(uint256, uint256) pure returns(uint256) -#define function min(uint256, uint256) pure returns(uint256) -#define function average(uint256, uint256) pure returns(uint256) -#define function ceilDiv(uint256, uint256) pure returns(uint256) - -// Negative 1 in two's compliment -#define constant NEG1 = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff - -/// @notice Calculates the square root of a stack input -#define macro SQRT() = takes (1) returns (1) { - // input stack // [num] - // if num == 0 return 0 - dup1 // [number, number] - iszero // [is_zero, number] - is_zero jumpi - - // assign stack vars - dup1 // [x, num] - 0x01 // [result, x, num] - - // if (x >> 128 > 0) { - // x >>= 128; - // result <<= 64; - // } - dup2 // [x, result, x, num] - 0x80 shr // [x >> 128, result, x, num] - dup1 // [x >> 128, x >> 128, result, x, num] - iszero // [x >> 128 == 0, x >> 128, result, x, num] - sh_128_0 jumpi - swap1 0x40 shl // [result, x >> 128, x, num] - swap1 swap2 // [x, result, x >> 128, num] - sh_128_0: - pop - - // if (x >> 64 > 0) { - // x >>= 64; - // result <<= 32; - // } - dup2 // [x, result, x, num] - 0x40 shr // [x >> 64, result, x, num] - dup1 // [x >> 64, x >> 64, result, x, num] - iszero // [x >> 64 == 0, x >> 64, result, x, num] - sh_64_0 jumpi - swap1 0x20 shl // [result, x >> 64, x, num] - swap1 swap2 // [x, result, x >> 64, num] - sh_64_0: - pop - - // if (x >> 32 > 0) { - // x >>= 32; - // result <<= 16; - // } - dup2 // [x, result, x, num] - 0x20 shr // [x >> 32, result, x, num] - dup1 // [x >> 32, x >> 32, result, x, num] - iszero // [x >> 32 == 0, x >> 32, result, x, num] - sh_32_0 jumpi - swap1 0x10 shl // [result, x >> 32, x, num] - swap1 swap2 // [x, result, x >> 32, num] - sh_32_0: - pop - - // if (x >> 16 > 0) { - // x >>= 16; - // result <<= 8; - // } - dup2 // [x, result, x, num] - 0x10 shr // [x >> 16, result, x, num] - dup1 // [x >> 16, x >> 16, result, x, num] - iszero // [x >> 16 == 0, x >> 16, result, x, num] - sh_16_0 jumpi - swap1 0x08 shl // [result, x >> 16, x, num] - swap1 swap2 // [x, result, x >> 16, num] - sh_16_0: - pop - - // if (x >> 8 > 0) { - // x >>= 8; - // result <<= 4; - // } - dup2 // [x, result, x, num] - 0x08 shr // [x >> 8, result, x, num] - dup1 // [x >> 8, x >> 8, result, x, num] - iszero // [x >> 8 == 0, x >> 8, result, x, num] - sh_8_0 jumpi - swap1 0x04 shl // [result, x >> 8, x, num] - swap1 swap2 // [x, result, x >> 8, num] - sh_8_0: - pop - - // if (x >> 4 > 0) { - // x >>= 4; - // result <<= 2; - // } - dup2 // [x, result, x, num] - 0x04 shr // [x >> 4, result, x, num] - dup1 // [x >> 4, x >> 4, result, x, num] - iszero // [x >> 4 == 0, x >> 4, result, x, num] - sh_4_0 jumpi - swap1 0x02 shl // [result, x >> 4, x, num] - swap1 swap2 // [x, result, x >> 4, num] - sh_4_0: - pop - - // if (x >> 2 > 0) { - // x >>= 2; - // result <<= 1; - // } - dup2 // [x, result, x, num] - 0x02 shr // [x >> 2, result, x, num] - dup1 // [x >> 2, x >> 2, result, x, num] - iszero // [x >> 2 == 0, x >> 2, result, x, num] - sh_2_0 jumpi - swap1 0x01 shl // [result, x >> 2, x, num] - swap1 swap2 // [x, result, x >> 2, num] - sh_2_0: - pop - - // result = (result + num / result) >> 1; - dup1 // [result, result, x, num] - dup4 // [num, result, result, x, num] - div // [num / result, result x, num] - add // [result + num / result, x, num] - 0x01 shr // [result, x, num] - - // result = (result + num / result) >> 1; - dup1 // [result, result, x, num] - dup4 // [num, result, result, x, num] - div // [num / result, result, x, num] - add // [result + num / result, x, num] - 0x01 shr // [result, x, num] - - // result = (result + num / result) >> 1; - dup1 // [result, result, x, num] - dup4 // [num, result, result, x, num] - div // [num / result, result, x, num] - add // [result + num / result, x, num] - 0x01 shr // [result, x, num] - - // result = (result + num / result) >> 1; - dup1 // [result, result, x, num] - dup4 // [num, result, result, x, num] - div // [num / result, result, x, num] - add // [result + num / result, x, num] - 0x01 shr // [result, x, num] - - // result = (result + num / result) >> 1; - dup1 // [result, result, x, num] - dup4 // [num, result, result, x, num] - div // [num / result, result, x, num] - add // [result + num / result, x, num] - 0x01 shr // [result, x, num] - - // result = (result + num / result) >> 1; - dup1 // [result, result, x, num] - dup4 // [num, result, result, x, num] - div // [num / result, result, x, num] - add // [result + num / result, x, num] - 0x01 shr // [result, x, num] - - // result = (result + num / result) >> 1; - dup1 // [result, result, x, num] - dup4 // [num, result, result, x, num] - div // [num / result, result, x, num] - add // [result + num / result, x, num] - 0x01 shr // [result, x, num] - - // result = min(result, num / result) - dup1 // [result, result, x, num] - swap3 // [num, result, x, result] - div // [num / result, x, result] - swap2 swap1 pop // [result, num / result] - MIN() - - is_zero: -} - -/// @notice Returns the maximum value of two values on the stack -#define macro MAX() = takes (2) returns (1) { - // input stack: // [num1, num2] - dup2 // [num2, num1, num2] - dup2 // [num1, num2, num1, num2] - lt // [is_less_than, num1, num2] - - less_than jumpi - swap1 // [num1, num2] - - less_than: - pop // [max(num2, num1)] -} - -/// @notice Returns the ceiling of the division of two values on the stack -#define macro CEIL_DIV() = takes (2) returns (1) { - // input stack: // [num1, num2] - dup1 iszero // [is_zero, num1, num2] - if_zero jumpi - - dup2 iszero // [is_zero, num1, num2] - divide_by_zero jumpi - - 0x01 // [1, num1, num2] - swap1 // [num1, 1, num1] - sub // [num1 - 1, num2] - div 0x01 add // [((num1 - 1) / num2) + 1] - dest jump - - divide_by_zero: - [DIVIDE_BY_ZERO] PANIC() - - if_zero: - swap1 // [num2, num1] - pop // [num1] - - dest: -} - -/// @notice Returns the minimum value of two values on the stack -#define macro MIN() = takes (2) returns (1) { - // input stack: // [num1, num2] - dup2 dup2 gt // [is_greater_than, num1, num2] - - greater_than jumpi - swap1 // [num2, num1] - - greater_than: - pop // [min(num1, num2)] -} - -/// @notice Returns the average of two values on the stack -#define macro AVG() = takes (2) returns (1) { - // input stack: // [num1, num2] - dup2 dup2 and // [num1 & num2, num1, num2] - swap2 // [num2, num1, num1 & num2] - xor // [num2 ^ num1, num1 & num2] - 0x02 swap1 div // [num2 ^ num1 / 2, num1 & num2] - add // [sum] -} - -/// @notice Unsafely subtracts 1 from a uint256 using the 2's complement representation -#define macro UNSAFE_SUB() = takes (1) returns (1) { - // Input Stack: [x] - // Output Stack: [x - 1] - - [NEG1] add // [x - 1] -} \ No newline at end of file diff --git a/src/math/__TEMP__wqcimbuhetstepqivcpdmtxszazlqpnnSafeMath.huff b/src/math/__TEMP__wqcimbuhetstepqivcpdmtxszazlqpnnSafeMath.huff deleted file mode 100644 index 8ac2256c..00000000 --- a/src/math/__TEMP__wqcimbuhetstepqivcpdmtxszazlqpnnSafeMath.huff +++ /dev/null @@ -1,153 +0,0 @@ - -// Wrapper methods (for testing) -#define macro SAFE_ADD_WRAPPER() = takes (0) returns (0) { - 0x04 calldataload // [num1] - 0x24 calldataload // [num2, num1] - SAFE_ADD() // [result] - 0x00 mstore // [] - 0x20 0x00 return // [] -} - -#define macro SAFE_SUB_WRAPPER() = takes (0) returns (0) { - 0x04 calldataload // [num1] - 0x24 calldataload // [num2, num1] - swap1 // [num1, num2] - SAFE_SUB() // [result] - 0x00 mstore // [] - 0x20 0x00 return // [] -} - -#define macro SAFE_MUL_WRAPPER() = takes (0) returns (0) { - 0x04 calldataload // [num1] - 0x24 calldataload // [num2, num1] - SAFE_MUL() // [result] - 0x00 mstore // [] - 0x20 0x00 return // [] -} - -#define macro SAFE_DIV_WRAPPER() = takes (0) returns (0) { - 0x04 calldataload // [num1] - 0x24 calldataload // [num2, num1] - swap1 // [num1, num2] - SAFE_DIV() // [result] - 0x00 mstore // [] - 0x20 0x00 return // [] -} - -#define macro SAFE_MOD_WRAPPER() = takes (0) returns (0) { - 0x04 calldataload // [num1] - 0x24 calldataload // [num2, num1] - swap1 // [num1, num2] - SAFE_MOD() // [result] - 0x00 mstore // [] - 0x20 0x00 return // [] -} - -// Main -#define macro MAIN() = takes (0) returns (0) { - 0x00 calldataload 0xE0 shr - dup1 __FUNC_SIG(safeAdd) eq safe_add jumpi - dup1 __FUNC_SIG(safeSub) eq safe_sub jumpi - dup1 __FUNC_SIG(safeMul) eq safe_mul jumpi - dup1 __FUNC_SIG(safeDiv) eq safe_div jumpi - dup1 __FUNC_SIG(safeMod) eq safe_mod jumpi - - 0x00 0x00 revert - - safe_add: - SAFE_ADD_WRAPPER() - safe_sub: - SAFE_SUB_WRAPPER() - safe_mul: - SAFE_MUL_WRAPPER() - safe_div: - SAFE_DIV_WRAPPER() - safe_mod: - SAFE_MOD_WRAPPER() -} - -/// @title SafeMath -/// @notice SPDX-License-Identifier: MIT -/// @author kadenzipfel -/// @notice Math module over Solidity's arithmetic operations with safety checks -/// @notice Adapted from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/math/SafeMath.sol) - -#include "../utils/Errors.huff" - -// Interface -#define function safeAdd(uint256,uint256) pure returns (uint256) -#define function safeSub(uint256,uint256) pure returns (uint256) -#define function safeMul(uint256,uint256) pure returns (uint256) -#define function safeDiv(uint256,uint256) pure returns (uint256) -#define function safeMod(uint256,uint256) pure returns (uint256) - -/// @notice Adds two numbers and reverts on overflow -#define macro SAFE_ADD() = takes (2) returns (1) { - // input stack // [num1, num2] - dup2 // [num2, num1, num2] - add // [result, num2] - dup1 // [result, result, num2] - swap2 // [num2, result, result] - gt // [is_overflow, result] - iszero // [is_not_overflow, result] - is_not_overflow jumpi // [result] - [ARITHMETIC_OVERFLOW] PANIC() - is_not_overflow: // [result] -} - -/// @notice Subtracts two numbers and reverts on underflow -#define macro SAFE_SUB() = takes (2) returns (1) { - // input stack // [num1, num2] - dup1 // [num1, num1, num2] - dup3 // [num2, num1, num1, num2] - gt // [is_underflow, num1, num2] - iszero // [is_not_underflow, num1, num2] - is_not_underflow jumpi // [num1, num2] - [ARITHMETIC_OVERFLOW] PANIC() - is_not_underflow: // [num1, num2] - sub // [result] -} - -/// @notice Multiplies two numbers and reverts on overflow -#define macro SAFE_MUL() = takes (2) returns (1) { - // input stack // [num1, num2] - dup1 // [num1, num1, num2] - is_not_zero jumpi // [num1, num2] - mul // [result] - 0x01 is_not_overflow jumpi - is_not_zero: // [num1, num2] - dup2 // [num2, num1, num2] - dup2 // [num1, num2, num1, num2] - mul // [result, num1, num2] - swap1 // [num1, result, num2] - dup2 // [result, num1, result, num2] - div // [div_check, result, num2] - swap1 // [result, div_check, num2] - swap2 // [num2, div_check, result] - eq // [is_not_overflow, result] - is_not_overflow jumpi // [result] - [ARITHMETIC_OVERFLOW] PANIC() - is_not_overflow: -} - -/// @notice Divides two numbers and reverts on division by zero -#define macro SAFE_DIV() = takes (2) returns (1) { - // input stack // [num1, num2] - 0x00 dup3 // [num2, 0, num1, num2] - gt // [is_not_div_zero, num1, num2] - is_not_div_zero jumpi - [DIVIDE_BY_ZERO] PANIC() - is_not_div_zero: - div // [result] -} - -/// @notice Divides two numbers and reverts on division by zero or modulo zero -#define macro SAFE_MOD() = takes (2) returns (1) { - // input stack // [num1, num2] - 0x00 dup3 // [num2, 0, num1, num2] - gt // [is_not_mod_zero, num1, num2] - is_not_mod_zero jumpi - [ARITHMETIC_OVERFLOW] PANIC() - is_not_mod_zero: - mod // [result] -} \ No newline at end of file diff --git a/src/mechanisms/huff-clones/__TEMP__hvlmmbwdwsqmdvneonbcfprxtzfbmhkuExampleClone.huff b/src/mechanisms/huff-clones/__TEMP__hvlmmbwdwsqmdvneonbcfprxtzfbmhkuExampleClone.huff deleted file mode 100644 index 5aca4ff7..00000000 --- a/src/mechanisms/huff-clones/__TEMP__hvlmmbwdwsqmdvneonbcfprxtzfbmhkuExampleClone.huff +++ /dev/null @@ -1,77 +0,0 @@ - - -/// @title ExampleClone -/// @notice SPDX-License-Identifier: MIT -/// @author wighawag -/// @author zefram -/// @author hari -/// @author z0r0z -/// @author clabby -/// @notice Clones with Immutable Args Library -/// @notice Adapted from wighawag (https://github.com/wighawag/clones-with-immutable-args/blob/master/src/ExampleClone.sol) - -#include "./HuffClone.huff" - -#define function param1() view returns (address) -#define function param2() view returns (uint256) -#define function param3() view returns (uint64) -#define function param4() view returns (uint8) -#define function param5(uint256) view returns (uint256[] memory) - -#define macro PARAM_1() = takes (0) returns (0) { - 0x00 GET_ARG_ADDRESS() // [arg_addr] - 0x00 mstore // [] - 0x20 0x00 return -} - -#define macro PARAM_2() = takes (0) returns (0) { - 0x14 GET_ARG_UINT_256() // [arg_uint] - 0x00 mstore // [] - 0x20 0x00 return -} - -#define macro PARAM_3() = takes (0) returns (0) { - 0x34 GET_ARG_UINT_64() // [arg_uint] - 0x00 mstore // [] - 0x20 0x00 return -} - -#define macro PARAM_4() = takes (0) returns (0) { - 0x3C GET_ARG_UINT_8() // [arg_uint] - 0x00 mstore // [] - 0x20 0x00 return -} - -#define macro PARAM_5() = takes (0) returns (0) { - 0x04 calldataload // [arr_len] - - // Store pointer in word before array - 0x20 0x00 mstore // [arr_len] - - dup1 0x00 // [0x00, arr_len, arr_len] - GET_ARG_UINT_256_ARR(0x20) // [ptr, arr_len] - swap1 // [arr_len, ptr] - 0x05 shl // [arr_len * 0x20, ptr] - 0x40 add // [arr_len * 0x20 + 0x40, ptr] - 0x00 return // [ptr] -} - -#define macro MAIN() = takes (0) returns (0) { - pc calldataload 0xE0 shr - dup1 __FUNC_SIG(param1) eq param1 jumpi - dup1 __FUNC_SIG(param2) eq param2 jumpi - dup1 __FUNC_SIG(param3) eq param3 jumpi - dup1 __FUNC_SIG(param4) eq param4 jumpi - dup1 __FUNC_SIG(param5) eq param5 jumpi - - param1: - PARAM_1() - param2: - PARAM_2() - param3: - PARAM_3() - param4: - PARAM_4() - param5: - PARAM_5() -} diff --git a/src/mechanisms/huff-clones/__TEMP__pgbwefuedeoorfkumjbbbagtfehbslnhExampleClone.huff b/src/mechanisms/huff-clones/__TEMP__pgbwefuedeoorfkumjbbbagtfehbslnhExampleClone.huff deleted file mode 100644 index 5aca4ff7..00000000 --- a/src/mechanisms/huff-clones/__TEMP__pgbwefuedeoorfkumjbbbagtfehbslnhExampleClone.huff +++ /dev/null @@ -1,77 +0,0 @@ - - -/// @title ExampleClone -/// @notice SPDX-License-Identifier: MIT -/// @author wighawag -/// @author zefram -/// @author hari -/// @author z0r0z -/// @author clabby -/// @notice Clones with Immutable Args Library -/// @notice Adapted from wighawag (https://github.com/wighawag/clones-with-immutable-args/blob/master/src/ExampleClone.sol) - -#include "./HuffClone.huff" - -#define function param1() view returns (address) -#define function param2() view returns (uint256) -#define function param3() view returns (uint64) -#define function param4() view returns (uint8) -#define function param5(uint256) view returns (uint256[] memory) - -#define macro PARAM_1() = takes (0) returns (0) { - 0x00 GET_ARG_ADDRESS() // [arg_addr] - 0x00 mstore // [] - 0x20 0x00 return -} - -#define macro PARAM_2() = takes (0) returns (0) { - 0x14 GET_ARG_UINT_256() // [arg_uint] - 0x00 mstore // [] - 0x20 0x00 return -} - -#define macro PARAM_3() = takes (0) returns (0) { - 0x34 GET_ARG_UINT_64() // [arg_uint] - 0x00 mstore // [] - 0x20 0x00 return -} - -#define macro PARAM_4() = takes (0) returns (0) { - 0x3C GET_ARG_UINT_8() // [arg_uint] - 0x00 mstore // [] - 0x20 0x00 return -} - -#define macro PARAM_5() = takes (0) returns (0) { - 0x04 calldataload // [arr_len] - - // Store pointer in word before array - 0x20 0x00 mstore // [arr_len] - - dup1 0x00 // [0x00, arr_len, arr_len] - GET_ARG_UINT_256_ARR(0x20) // [ptr, arr_len] - swap1 // [arr_len, ptr] - 0x05 shl // [arr_len * 0x20, ptr] - 0x40 add // [arr_len * 0x20 + 0x40, ptr] - 0x00 return // [ptr] -} - -#define macro MAIN() = takes (0) returns (0) { - pc calldataload 0xE0 shr - dup1 __FUNC_SIG(param1) eq param1 jumpi - dup1 __FUNC_SIG(param2) eq param2 jumpi - dup1 __FUNC_SIG(param3) eq param3 jumpi - dup1 __FUNC_SIG(param4) eq param4 jumpi - dup1 __FUNC_SIG(param5) eq param5 jumpi - - param1: - PARAM_1() - param2: - PARAM_2() - param3: - PARAM_3() - param4: - PARAM_4() - param5: - PARAM_5() -} diff --git a/src/mechanisms/huff-clones/__TEMP__xhkqnmmjajsmfrshnyoafedbhvmybxcfExampleClone.huff b/src/mechanisms/huff-clones/__TEMP__xhkqnmmjajsmfrshnyoafedbhvmybxcfExampleClone.huff deleted file mode 100644 index 5aca4ff7..00000000 --- a/src/mechanisms/huff-clones/__TEMP__xhkqnmmjajsmfrshnyoafedbhvmybxcfExampleClone.huff +++ /dev/null @@ -1,77 +0,0 @@ - - -/// @title ExampleClone -/// @notice SPDX-License-Identifier: MIT -/// @author wighawag -/// @author zefram -/// @author hari -/// @author z0r0z -/// @author clabby -/// @notice Clones with Immutable Args Library -/// @notice Adapted from wighawag (https://github.com/wighawag/clones-with-immutable-args/blob/master/src/ExampleClone.sol) - -#include "./HuffClone.huff" - -#define function param1() view returns (address) -#define function param2() view returns (uint256) -#define function param3() view returns (uint64) -#define function param4() view returns (uint8) -#define function param5(uint256) view returns (uint256[] memory) - -#define macro PARAM_1() = takes (0) returns (0) { - 0x00 GET_ARG_ADDRESS() // [arg_addr] - 0x00 mstore // [] - 0x20 0x00 return -} - -#define macro PARAM_2() = takes (0) returns (0) { - 0x14 GET_ARG_UINT_256() // [arg_uint] - 0x00 mstore // [] - 0x20 0x00 return -} - -#define macro PARAM_3() = takes (0) returns (0) { - 0x34 GET_ARG_UINT_64() // [arg_uint] - 0x00 mstore // [] - 0x20 0x00 return -} - -#define macro PARAM_4() = takes (0) returns (0) { - 0x3C GET_ARG_UINT_8() // [arg_uint] - 0x00 mstore // [] - 0x20 0x00 return -} - -#define macro PARAM_5() = takes (0) returns (0) { - 0x04 calldataload // [arr_len] - - // Store pointer in word before array - 0x20 0x00 mstore // [arr_len] - - dup1 0x00 // [0x00, arr_len, arr_len] - GET_ARG_UINT_256_ARR(0x20) // [ptr, arr_len] - swap1 // [arr_len, ptr] - 0x05 shl // [arr_len * 0x20, ptr] - 0x40 add // [arr_len * 0x20 + 0x40, ptr] - 0x00 return // [ptr] -} - -#define macro MAIN() = takes (0) returns (0) { - pc calldataload 0xE0 shr - dup1 __FUNC_SIG(param1) eq param1 jumpi - dup1 __FUNC_SIG(param2) eq param2 jumpi - dup1 __FUNC_SIG(param3) eq param3 jumpi - dup1 __FUNC_SIG(param4) eq param4 jumpi - dup1 __FUNC_SIG(param5) eq param5 jumpi - - param1: - PARAM_1() - param2: - PARAM_2() - param3: - PARAM_3() - param4: - PARAM_4() - param5: - PARAM_5() -} diff --git a/src/mechanisms/huff-clones/__TEMP__xpmxrssqgllfjrqfvrmjmhzvpeefnmpcExampleClone.huff b/src/mechanisms/huff-clones/__TEMP__xpmxrssqgllfjrqfvrmjmhzvpeefnmpcExampleClone.huff deleted file mode 100644 index 5aca4ff7..00000000 --- a/src/mechanisms/huff-clones/__TEMP__xpmxrssqgllfjrqfvrmjmhzvpeefnmpcExampleClone.huff +++ /dev/null @@ -1,77 +0,0 @@ - - -/// @title ExampleClone -/// @notice SPDX-License-Identifier: MIT -/// @author wighawag -/// @author zefram -/// @author hari -/// @author z0r0z -/// @author clabby -/// @notice Clones with Immutable Args Library -/// @notice Adapted from wighawag (https://github.com/wighawag/clones-with-immutable-args/blob/master/src/ExampleClone.sol) - -#include "./HuffClone.huff" - -#define function param1() view returns (address) -#define function param2() view returns (uint256) -#define function param3() view returns (uint64) -#define function param4() view returns (uint8) -#define function param5(uint256) view returns (uint256[] memory) - -#define macro PARAM_1() = takes (0) returns (0) { - 0x00 GET_ARG_ADDRESS() // [arg_addr] - 0x00 mstore // [] - 0x20 0x00 return -} - -#define macro PARAM_2() = takes (0) returns (0) { - 0x14 GET_ARG_UINT_256() // [arg_uint] - 0x00 mstore // [] - 0x20 0x00 return -} - -#define macro PARAM_3() = takes (0) returns (0) { - 0x34 GET_ARG_UINT_64() // [arg_uint] - 0x00 mstore // [] - 0x20 0x00 return -} - -#define macro PARAM_4() = takes (0) returns (0) { - 0x3C GET_ARG_UINT_8() // [arg_uint] - 0x00 mstore // [] - 0x20 0x00 return -} - -#define macro PARAM_5() = takes (0) returns (0) { - 0x04 calldataload // [arr_len] - - // Store pointer in word before array - 0x20 0x00 mstore // [arr_len] - - dup1 0x00 // [0x00, arr_len, arr_len] - GET_ARG_UINT_256_ARR(0x20) // [ptr, arr_len] - swap1 // [arr_len, ptr] - 0x05 shl // [arr_len * 0x20, ptr] - 0x40 add // [arr_len * 0x20 + 0x40, ptr] - 0x00 return // [ptr] -} - -#define macro MAIN() = takes (0) returns (0) { - pc calldataload 0xE0 shr - dup1 __FUNC_SIG(param1) eq param1 jumpi - dup1 __FUNC_SIG(param2) eq param2 jumpi - dup1 __FUNC_SIG(param3) eq param3 jumpi - dup1 __FUNC_SIG(param4) eq param4 jumpi - dup1 __FUNC_SIG(param5) eq param5 jumpi - - param1: - PARAM_1() - param2: - PARAM_2() - param3: - PARAM_3() - param4: - PARAM_4() - param5: - PARAM_5() -} diff --git a/src/mechanisms/huff-vrgda/__TEMP__emehkakqdlyztnvsbkuhzfucpimehhtdLogisticVRGDA.huff b/src/mechanisms/huff-vrgda/__TEMP__emehkakqdlyztnvsbkuhzfucpimehhtdLogisticVRGDA.huff deleted file mode 100644 index 61963e7c..00000000 --- a/src/mechanisms/huff-vrgda/__TEMP__emehkakqdlyztnvsbkuhzfucpimehhtdLogisticVRGDA.huff +++ /dev/null @@ -1,77 +0,0 @@ - -#define function getTargetSaleTime(int256) view returns (int256) -#define function getVRGDAPrice(int256, uint256) view returns (uint256) - -// Getters to demonstrate how to override constants in huff -#define function targetPrice() view returns(int256) -#define function decayConstant() view returns(int256) -#define function timeScale() view returns(int256) -#define function logisticLimit() view returns(int256) -#define function logisticLimitDoubled() view returns(int256) - - -#define macro MAIN() = { - pc calldataload 0xE0 shr - dup1 __FUNC_SIG(getVRGDAPrice) eq getVRGDAPrice jumpi - dup1 __FUNC_SIG(getTargetSaleTime) eq getTargetSaleTime jumpi - dup1 __FUNC_SIG(targetPrice) eq targetPrice jumpi - dup1 __FUNC_SIG(decayConstant) eq decayConstant jumpi - dup1 __FUNC_SIG(timeScale) eq timeScale jumpi - dup1 __FUNC_SIG(logisticLimit) eq logisticLimit jumpi - dup1 __FUNC_SIG(logisticLimitDoubled) eq logisticLimitDoubled jumpi - - fail: - 0x00 dup1 revert - - getVRGDAPrice: - GET_VRGDA_PRICE_EXTERNAL(fail) - getTargetSaleTime: - GET_TARGET_SALE_TIME_EXTERNAL(fail) - targetPrice: - RETURN_CONSTANT(TARGET_PRICE) - decayConstant: - RETURN_CONSTANT(DECAY_CONSTANT) - timeScale: - RETURN_CONSTANT(TIME_SCALE) - logisticLimit: - RETURN_CONSTANT(LOGISTIC_LIMIT) - logisticLimitDoubled: - RETURN_CONSTANT(LOGISTIC_LIMIT_DOUBLED) -} - - -/// @title Logistic Variable Rate Gradual Dutch Auction -/// @notice SPDX-License-Identifier: MIT -/// @author transmissions11 -/// @author FrankieIsLost -/// @author Maddiaa -/// @notice VRGDA with a logistic issuance curve. -/// @notice Original Implementation by Maddiaa (https://github.com/cheethas/huff-vrgda/blob/main/src/LogisticVRGDA.huff) - -#include "./VRGDA.huff" - -#define constant LOGISTIC_LIMIT = 0x00 // ( int256 ) -#define constant LOGISTIC_LIMIT_DOUBLED = 0x00 // ( int256 ) -#define constant TIME_SCALE = 0x00 // ( int256 ) - -/// @dev Given a number of tokens sold, return the target time that number of tokens should be sold by. -/// @param {Stack} sold A number of tokens sold, scaled by 1e18, to get the corresponding target sale time for. -/// @return The target time the tokens should be sold by, scaled by 1e18, where the time is -/// relative, such that 0 means the tokens should be sold immediately when the VRGDA begins. -#define macro GET_TARGET_SALE_TIME(fail) = takes (1) returns (0) { - // init state = [sold] - [TIME_SCALE] // [timeScale, sold] - swap1 // [sold, perTimeUnit] - - [WAD] // [1e18, sold, timescale] - swap1 // [sold, 1e18, timescale] - [LOGISTIC_LIMIT] // [logisticLimit, sold, 1e18, timeScale] - add // [sold + logisticLimit, 1e18, timeScale] - [LOGISTIC_LIMIT_DOUBLED] // [logisticLimitDoubled, (sold+logisticLimit), 1e18, timeScale] - UNSAFE_WAD_DIV() // [(logisticLimitDoubled / (sold + logisticLimit)), 1e18, timeScale] - sub // [((logisticLimitDoubled / (sold + logisticLimit)) - 1e18), timeScale] - - LN_WAD(fail) // [wadLn((logisticLimitDoubled / (sold + logisticLimit)) - 1e18), timeScale] - UNSAFE_WAD_DIV() // [wadLn((logisticLimitDoubled / (sold + logisticLimit)) - 1e18) / timeScale] - 0x00 sub // [-wadLn((logisticLimitDoubled / (sold + logisticLimit)) - 1e18) / timeScale] -} diff --git a/src/mechanisms/huff-vrgda/__TEMP__fldyysnwnrmtgswdmaharirrkhhznvgtLinearVRGDA.huff b/src/mechanisms/huff-vrgda/__TEMP__fldyysnwnrmtgswdmaharirrkhhznvgtLinearVRGDA.huff deleted file mode 100644 index dfa3ff88..00000000 --- a/src/mechanisms/huff-vrgda/__TEMP__fldyysnwnrmtgswdmaharirrkhhznvgtLinearVRGDA.huff +++ /dev/null @@ -1,57 +0,0 @@ - -#define function getTargetSaleTime(int256) view returns (int256) -#define function getVRGDAPrice(int256, uint256) view returns (uint256) -#define function targetPrice() view returns (int256) -#define function decayConstant() view returns (int256) -#define function perTimeUnit() view returns (int256) - - -#define macro MAIN() = { - 0x00 calldataload 0xE0 shr - dup1 __FUNC_SIG(getVRGDAPrice) eq getVRGDAPrice jumpi - dup1 __FUNC_SIG(getTargetSaleTime) eq getTargetSaleTime jumpi - dup1 __FUNC_SIG(targetPrice) eq targetPrice jumpi - dup1 __FUNC_SIG(decayConstant) eq decayConstant jumpi - dup1 __FUNC_SIG(perTimeUnit) eq perTimeUnit jumpi - - fail: - 0x00 dup1 revert - - getVRGDAPrice: - GET_VRGDA_PRICE_EXTERNAL(fail) - getTargetSaleTime: - GET_TARGET_SALE_TIME_EXTERNAL(fail) - targetPrice: - RETURN_CONSTANT(TARGET_PRICE) - decayConstant: - RETURN_CONSTANT(DECAY_CONSTANT) - perTimeUnit: - RETURN_CONSTANT(PER_TIME_UNIT) -} - - -/// @title Linear Variable Rate Gradual Dutch Auction -/// @notice SPDX-License-Identifier: MIT -/// @author transmissions11 -/// @author FrankieIsLost -/// @author Maddiaa -/// @notice VRGDA with a linear issuance curve. -/// @notice Original Implementation by Maddiaa (https://github.com/cheethas/huff-vrgda/blob/main/src/LinearVRGDA.huff) - -#include "./VRGDA.huff" - -// These will be overriden with the constructor flag -// The constructor logic will need to be copied within deploy scripts -// in order to inline the correct constants -#define constant PER_TIME_UNIT = 0x00 // ( int256 ) - -/// @dev Given a number of tokens sold, return the target time that number of tokens should be sold by. -/// @param {stack} sold A number of tokens sold, scaled by 1e18, to get the corresponding target sale time for. -/// @return The target time the tokens should be sold by, scaled by 1e18, where the time is -/// relative, such that 0 means the tokens should be sold immediately when the VRGDA begins. -#define macro GET_TARGET_SALE_TIME() = takes (1) returns (0) { - // init state = [sold] - [PER_TIME_UNIT] // [perTimeUnit, sold] - swap1 // [sold, perTimeUnit] - UNSAFE_WAD_DIV() // [sold / perTimeUnit] (targetSaleTime) -} diff --git a/src/proxies/__TEMP__flavwmvnufiarmtrrvilwbhnhmfuxofvClones.huff b/src/proxies/__TEMP__flavwmvnufiarmtrrvilwbhnhmfuxofvClones.huff deleted file mode 100644 index cea3c8f3..00000000 --- a/src/proxies/__TEMP__flavwmvnufiarmtrrvilwbhnhmfuxofvClones.huff +++ /dev/null @@ -1,213 +0,0 @@ -#define function clone(address) nonpayable returns (address) -#define function cloneDeterministic(address,bytes32) nonpayable returns (address) -#define function predictDeterministicAddress(address,bytes32) view returns (address) -// #define function predictDeterministicAddress(address,bytes32,address) view returns (address) - -#define macro CLONE_WRAPPER() = { - 0x04 calldataload // [implementation] - CLONE() // [address] - 0x00 mstore // [] - 0x20 0x00 return // return address -} - -#define macro CLONE_DETERMINISTIC_WRAPPER() = { - 0x24 calldataload // [salt] - 0x04 calldataload // [implementation, salt] - CLONE_DETERMINISTIC() // [address] - 0x00 mstore // [] - 0x20 0x00 return // return address -} - -#define macro PREDICT_DETERMINISTIC_ADDRESS_WRAPPER() = { - address // [address(this)] - 0x24 calldataload // [salt, address(this)] - 0x04 calldataload // [implementation, salt, address(this)] - PREDICT_DETERMINISTIC_ADDRESS(0x40) // [address] - 0x00 mstore // [] - 0x20 0x00 return // return address -} - -#define macro PREDICT_DETERMINISTIC_ADDRESS_DEPLOYER_WRAPPER() = { - 0x44 calldataload // [deployer] - 0x24 calldataload // [salt, deployer] - 0x04 calldataload // [implementation, salt, deployer] - PREDICT_DETERMINISTIC_ADDRESS(0x40) // [address] - 0x00 mstore // [] - 0x20 0x00 return // return address -} - -#define macro MAIN() = { - pc calldataload 0xe0 shr - - dup1 __FUNC_SIG(clone) eq clone_jump jumpi - dup1 __FUNC_SIG(cloneDeterministic) eq clone_deterministic_jump jumpi - dup1 __FUNC_SIG(predictDeterministicAddress) eq predict_deterministic_address_jump jumpi - dup1 __FUNC_SIG("predictDeterministicAddress(address,bytes32,address)") eq predict_deterministic_address_deployer_jump jumpi - - // Exit is selector does not match - 0x00 dup1 revert - - clone_jump: - CLONE_WRAPPER() - clone_deterministic_jump: - CLONE_DETERMINISTIC_WRAPPER() - predict_deterministic_address_jump: - PREDICT_DETERMINISTIC_ADDRESS_WRAPPER() - predict_deterministic_address_deployer_jump: - PREDICT_DETERMINISTIC_ADDRESS_DEPLOYER_WRAPPER() -} - -/// @title Clones -/// @notice SPDX-License-Identifier: MIT -/// @author Maddiaa -/// @author asnared -/// @notice https://eips.ethereum.org/EIPS/eip-1167[EIP 1167] is a standard for deploying minimal proxy contracts, also known as "clones". -/// @notice To simply and cheaply clone contract functionality in an immutable way, this standard specifies -/// a minimal bytecode implementation that delegates all calls to a known, fixed address. -/// -/// @notice The library includes functions to deploy a proxy using either `create` (traditional deployment) or `create2` -/// (salted deterministic deployment). It also includes functions to predict the addresses of clones deployed using the -/// deterministic method. -/// @notice Adapted from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/proxy/Clones.sol) - -#include "./ERC1967Upgrade.huff" -#include "../utils/CommonErrors.huff" - -// BEFORE ADDRESS -//--------------------------------------------------------------------------------// -// Opcode | Opcode + Arguments | Description | Stack View // -//--------------------------------------------------------------------------------// -// 0x3d | 0x36 | RETURNDATASIZE | 0 // -// 0x60 | 0x602d | PUSH1 0x2d | 0x2d 0 // -// 0x80 | 0x36 | DUP1 | 0x2d 0x2d 0 // -// 0x60 | 0x600a | PUSH1 0x0a | 0x0a 0x2d 0x2d 0 // -// 0x3d | 0x3d | RETURNDATASIZE | 0 0x0a 0x2d 0x2d 0 // -// 0x39 | 0x39 | CODECOPY | 0x2d 0 // -// 0x81 | 0x81 | DUP2 | 0 0x2d 0 // -// 0xf3 | 0xf3 | RETURN | 0 // - -// 0x36 | 0x36 | CALLDATASIZE | size // -// 0x3d | 0x3d | RETURNDATASIZE | 0 size // -// 0x3d | 0x3d | RETURNDATASIZE | 0 0 size // -// 0x37 | 0x37 | CALLDATACOPY | // -// 0x3d | 0x3d | RETURNDATASIZE | 0 // -// 0x3d | 0x3d | RETURNDATASIZE | 0 0 // -// 0x3d | 0x3d | RETURNDATASIZE | 0 0 0 // -// 0x36 | 0x36 | CALLDATASIZE | size 0 0 0 // -// 0x3d | 0x3d | RETURNDATASIZE | 0 size 0 0 0 // -// 0x73 | 0x73 | PUSH20 | addr 0 size 0 0 0 // - -// AFTER ADDRESS -//--------------------------------------------------------------------------------// -// Opcode | Opcode + Arguments | Description | Stack View // -//--------------------------------------------------------------------------------// -// 0x5a | 0x5a | GAS | gas addr 0 size 0 0 0 // -// 0xf4 | 0xf4 | DELEGATECALL | success 0 // -// 0x3d | 0x3d | RETURNDATASIZE | rds success 0 // -// 0x82 | 0x82 | DUP3 | 0 rds success 0 // -// 0x80 | 0x80 | DUP1 | 0 0 rds success 0 // -// 0x3e | 0x3e | RETURNDATACOPY | success 0 // -// 0x90 | 0x90 | SWAP1 | 0 success // -// 0x3d | 0x3d | RETURNDATASIZE | rds 0 success // -// 0x91 | 0x91 | SWAP2 | success rds 0 // -// 0x60 | 0x602b | PUSH1 0x2b | 0x2b success rds 0 // -// 0x57 | 0x57 | JUMPI | Revert if success == 0 // -// 0xfd | 0xfd | REVERT | // -// 0x5b | 0x5b | JUMPDEST | // -// 0xf3 | 0xf3 | RETURN | // -//--------------------------------------------------------------------------------// - -#define constant BYTECODE_BEFORE_ADDRESS = 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000 -#define constant BYTECODE_AFTER_ADDRESS = 0x5af43d82803e903d91602b57fd5bf3 - -/// @notice Clone a contract using `create`. -/// @param {Stack} Implementation - address of the contract to clone. -#define macro CLONE() = takes (1) returns (1) { - CLONE_MACRO(create) -} - -/// @notice Clone a contract to a deterministic address using `create2`. -/// @param {Stack} Implementation - address of the contract to clone. -/// @param {Stack} Salt - The salt to be added to create2. -#define macro CLONE_DETERMINISTIC() = takes (2) returns (1) { - CLONE_MACRO(create2) -} - -/// @dev Can remain inside the scratch space therefore no memory pointer is required -#define macro CLONE_MACRO(deploy_opcode) = takes (2) returns (1) { - // Input Stack: [implementation, salt [optional]] - - // Store the prefix - __RIGHTPAD(0x3d602d80600a3d3981f3363d3d373d3d3d363d73) // [prefix, implementation, salt] - 0x00 mstore // [implementation, salt] - - // Place the implementation at memory byte 20 - 0x60 shl // [rightpad(implementation), salt] - 0x14 mstore // [salt] - - // Add the suffix after the implementation at byte 40 - __RIGHTPAD(0x5af43d82803e903d91602b57fd5bf3) // [suffix, salt] - 0x28 mstore // [salt] - - // Create the contract - 0x37 // [0x37, salt] - 0x00 // [0x00, 0x37, salt] - 0x00 // [0x00, 0x00, 0x37, salt] - // [address] * This will be create | create2 - - // Throw exception if deployment fails - dup1 iszero create_failed jumpi // [address] - continue jump - - create_failed: - DEPLOYMENT_FAILED(0x00) - - continue: -} - - -/// @dev Memory pointer required as this function nukes memory and this is part of a library -#define macro PREDICT_DETERMINISTIC_ADDRESS(ptr) = takes (3) returns (1) { - // Input Stack: [implementation, salt, deployer] - swap1 swap2 swap1 // [implementation, deployer, salt] - - // Store the creation code prefix at memory byte 0 - __RIGHTPAD(0x3d602d80600a3d3981f3363d3d373d3d3d363d73) // [prefix, implementation, deployer, salt] - mstore // [implementation, deployer, salt] - - // Store the implementation address at memory byte 20 - 0x60 shl // [rightpad(implementation), deployer, salt] - 0x14 add // [ptr + 0x14, implementation, deployer, salt] - mstore // [deployer, salt] - - // Store the creation code suffix at memory byte 40 - __RIGHTPAD(0x5af43d82803e903d91602b57fd5bf3ff) // [bytecode_after, deployer, salt] - 0x28 add // [ptr + 0x28, bytecode_after, deployer, salt] - mstore // [deployer, salt] - - // mstore(add(ptr, 0x38), deployer) - 0x60 shl // [rightpad(deployer), salt] - 0x38 add // [ptr + 0x38, deployer, salt] - mstore // [salt] - - // mstore(add(ptr, 0x58), salt) - 0x4c add // [ptr + 0x58, salt] - mstore // [] - - // Hash and then store in memory - 0x37 // [0x37] - // [ptr, 0x37] - sha3 // [hash] - - 0x6c add // [ptr + 0x6c, hash] - mstore // [] - - // Hash the rest of the data - 0x55 // [0x55] - 0x37 add // [ptr + 0x37, 0x55] - sha3 // [hash] - - // Clean the upper 96 bits (12 bytes) of the hash - // The remaining 160 bits (20 bytes) are the address - 0x60 shl 0x60 shr // [clean(hash)] -} \ No newline at end of file diff --git a/src/proxies/__TEMP__klhwbuerlnsihsjssxbghxugniamuyipERC1967Proxy.huff b/src/proxies/__TEMP__klhwbuerlnsihsjssxbghxugniamuyipERC1967Proxy.huff deleted file mode 100644 index 63eb9ef3..00000000 --- a/src/proxies/__TEMP__klhwbuerlnsihsjssxbghxugniamuyipERC1967Proxy.huff +++ /dev/null @@ -1,158 +0,0 @@ -// Functions -// Implementation -#define function implementation() nonpayable returns (address) -#define function upgradeTo(address) nonpayable returns () -#define function upgradeToAndCall(address,bytes,bool) nonpayable returns () -#define function upgradeToAndCallUUPS(address,bytes,bool) nonpayable returns () - -// Admin -#define function admin() view returns (address) -#define function changeAdmin(address) nonpayable returns () - -// Beacon -#define function beacon() view returns (address) -#define function setBeacon(address) nonpayable returns () -#define function upgradeBeaconAndCall(address,bytes,bool) nonpayable returns () - - -// Implementations -#define macro IMPLEMENTATION_WRAPPER() = { - IMPLEMENTATION() - 0x00 mstore - 0x20 0x00 return -} - -#define macro UPGRADE_TO_WRAPPER() = { - 0x04 calldataload - UPGRADE_TO() - stop -} - -#define macro UPGRADE_TO_AND_CALL_WRAPPER() = { - 0x44 calldataload // [forceCall] - 0x24 calldataload // [data, forceCall] - 0x04 calldataload // [implementation, data, forceCall] - UPGRADE_TO_AND_CALL() - stop -} - -#define macro UPGRADE_TO_AND_CALL_UUPS_WRAPPER() = { - 0x44 calldataload // [forceCall] - 0x24 calldataload // [data, forceCall] - 0x04 calldataload // [implementation, data, forceCall] - UPGRADE_TO_AND_CALL_UUPS() - stop -} - -// Admin -#define macro GET_ADMIN_WRAPPER() = { - GET_ADMIN() - 0x00 mstore - 0x20 0x00 return -} - -#define macro CHANGE_ADMIN_WRAPPER() = { - 0x04 calldataload - CHANGE_ADMIN() - stop -} - - -// Beacon -#define macro GET_BEACON_WRAPPER() = { - GET_BEACON() - 0x00 mstore - 0x20 0x00 return -} - -#define macro SET_BEACON_WRAPPER() = { - 0x04 calldataload - SET_BEACON() - stop -} - -#define macro UPGRADE_BEACON_TO_AND_CALL_WRAPPER() = { - 0x44 calldataload // [forceCall] - 0x24 calldataload // [data, forceCall] - 0x04 calldataload // [implementation, data, forceCall] - UPGRADE_TO_BEACON_AND_CALL() - stop -} - - -// For the sake of this example, the owner will be passed in -#define macro CONSTRUCTOR() = { - // ERC1967_PROXY_CONSTRUCTOR() - - 0x20 - 0x20 codesize sub - 0x00 - codecopy - 0x00 mload - - SET_ADMIN() -} - -#define macro MAIN() = { - pc calldataload 0xe0 shr - - dup1 __FUNC_SIG(implementation) eq implementation jumpi - dup1 __FUNC_SIG(upgradeTo) eq upgradeTo jumpi - dup1 __FUNC_SIG(upgradeToAndCall) eq upgradeToAndCall jumpi - dup1 __FUNC_SIG(upgradeToAndCallUUPS) eq upgradeToAndCallUUPS jumpi - - dup1 __FUNC_SIG(admin) eq getAdmin jumpi - dup1 __FUNC_SIG(changeAdmin) eq changeAdmin jumpi - - dup1 __FUNC_SIG(beacon) eq getBeacon jumpi - dup1 __FUNC_SIG(setBeacon) eq setBeacon jumpi - dup1 __FUNC_SIG(upgradeBeaconAndCall) eq upgradeBeaconAndCall jumpi - - GET_IMPLEMENTATION() // [implementation] - DELEGATE() - - implementation: - IMPLEMENTATION_WRAPPER() - upgradeTo: - UPGRADE_TO_WRAPPER() - upgradeToAndCall: - UPGRADE_TO_AND_CALL_WRAPPER() - upgradeToAndCallUUPS: - UPGRADE_TO_AND_CALL_UUPS_WRAPPER() - - getAdmin: - GET_ADMIN_WRAPPER() - changeAdmin: - CHANGE_ADMIN_WRAPPER() - - getBeacon: - GET_BEACON_WRAPPER() - setBeacon: - SET_BEACON_WRAPPER() - upgradeBeaconAndCall: - UPGRADE_BEACON_TO_AND_CALL_WRAPPER() - -} - -/// @title ERC1967 Proxy -/// @notice SPDX-License-Identifier: MIT -/// @author asnared -/// @notice An upgradeable proxy that uses the ERC1967 storage layout. -/// @notice Adapted from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/proxy/ERC1967/ERC1967Proxy.sol) - -#include "./Proxy.huff" -#include "./ERC1967Upgrade.huff" - -/// @notice An internal constructor that upgrades the proxy to the implementation and calls the implementation -#define macro ERC1967_PROXY_CONSTRUCTOR() = takes (0) returns (0) { - 0x00 // [forceCall] - 0x24 calldataload // [data, forceCall] - 0x04 calldataload // [address, data, forceCall] - UPGRADE_TO_AND_CALL() // [] -} - -/// @notice Returns the current implementation address -/// @notice Overrideable -#define macro IMPLEMENTATION() = takes (0) returns (1) { - GET_IMPLEMENTATION() -} diff --git a/src/proxies/__TEMP__xlwhmiuazdwnqpgoxdvgcsfczvtfymagClones.huff b/src/proxies/__TEMP__xlwhmiuazdwnqpgoxdvgcsfczvtfymagClones.huff deleted file mode 100644 index cea3c8f3..00000000 --- a/src/proxies/__TEMP__xlwhmiuazdwnqpgoxdvgcsfczvtfymagClones.huff +++ /dev/null @@ -1,213 +0,0 @@ -#define function clone(address) nonpayable returns (address) -#define function cloneDeterministic(address,bytes32) nonpayable returns (address) -#define function predictDeterministicAddress(address,bytes32) view returns (address) -// #define function predictDeterministicAddress(address,bytes32,address) view returns (address) - -#define macro CLONE_WRAPPER() = { - 0x04 calldataload // [implementation] - CLONE() // [address] - 0x00 mstore // [] - 0x20 0x00 return // return address -} - -#define macro CLONE_DETERMINISTIC_WRAPPER() = { - 0x24 calldataload // [salt] - 0x04 calldataload // [implementation, salt] - CLONE_DETERMINISTIC() // [address] - 0x00 mstore // [] - 0x20 0x00 return // return address -} - -#define macro PREDICT_DETERMINISTIC_ADDRESS_WRAPPER() = { - address // [address(this)] - 0x24 calldataload // [salt, address(this)] - 0x04 calldataload // [implementation, salt, address(this)] - PREDICT_DETERMINISTIC_ADDRESS(0x40) // [address] - 0x00 mstore // [] - 0x20 0x00 return // return address -} - -#define macro PREDICT_DETERMINISTIC_ADDRESS_DEPLOYER_WRAPPER() = { - 0x44 calldataload // [deployer] - 0x24 calldataload // [salt, deployer] - 0x04 calldataload // [implementation, salt, deployer] - PREDICT_DETERMINISTIC_ADDRESS(0x40) // [address] - 0x00 mstore // [] - 0x20 0x00 return // return address -} - -#define macro MAIN() = { - pc calldataload 0xe0 shr - - dup1 __FUNC_SIG(clone) eq clone_jump jumpi - dup1 __FUNC_SIG(cloneDeterministic) eq clone_deterministic_jump jumpi - dup1 __FUNC_SIG(predictDeterministicAddress) eq predict_deterministic_address_jump jumpi - dup1 __FUNC_SIG("predictDeterministicAddress(address,bytes32,address)") eq predict_deterministic_address_deployer_jump jumpi - - // Exit is selector does not match - 0x00 dup1 revert - - clone_jump: - CLONE_WRAPPER() - clone_deterministic_jump: - CLONE_DETERMINISTIC_WRAPPER() - predict_deterministic_address_jump: - PREDICT_DETERMINISTIC_ADDRESS_WRAPPER() - predict_deterministic_address_deployer_jump: - PREDICT_DETERMINISTIC_ADDRESS_DEPLOYER_WRAPPER() -} - -/// @title Clones -/// @notice SPDX-License-Identifier: MIT -/// @author Maddiaa -/// @author asnared -/// @notice https://eips.ethereum.org/EIPS/eip-1167[EIP 1167] is a standard for deploying minimal proxy contracts, also known as "clones". -/// @notice To simply and cheaply clone contract functionality in an immutable way, this standard specifies -/// a minimal bytecode implementation that delegates all calls to a known, fixed address. -/// -/// @notice The library includes functions to deploy a proxy using either `create` (traditional deployment) or `create2` -/// (salted deterministic deployment). It also includes functions to predict the addresses of clones deployed using the -/// deterministic method. -/// @notice Adapted from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/proxy/Clones.sol) - -#include "./ERC1967Upgrade.huff" -#include "../utils/CommonErrors.huff" - -// BEFORE ADDRESS -//--------------------------------------------------------------------------------// -// Opcode | Opcode + Arguments | Description | Stack View // -//--------------------------------------------------------------------------------// -// 0x3d | 0x36 | RETURNDATASIZE | 0 // -// 0x60 | 0x602d | PUSH1 0x2d | 0x2d 0 // -// 0x80 | 0x36 | DUP1 | 0x2d 0x2d 0 // -// 0x60 | 0x600a | PUSH1 0x0a | 0x0a 0x2d 0x2d 0 // -// 0x3d | 0x3d | RETURNDATASIZE | 0 0x0a 0x2d 0x2d 0 // -// 0x39 | 0x39 | CODECOPY | 0x2d 0 // -// 0x81 | 0x81 | DUP2 | 0 0x2d 0 // -// 0xf3 | 0xf3 | RETURN | 0 // - -// 0x36 | 0x36 | CALLDATASIZE | size // -// 0x3d | 0x3d | RETURNDATASIZE | 0 size // -// 0x3d | 0x3d | RETURNDATASIZE | 0 0 size // -// 0x37 | 0x37 | CALLDATACOPY | // -// 0x3d | 0x3d | RETURNDATASIZE | 0 // -// 0x3d | 0x3d | RETURNDATASIZE | 0 0 // -// 0x3d | 0x3d | RETURNDATASIZE | 0 0 0 // -// 0x36 | 0x36 | CALLDATASIZE | size 0 0 0 // -// 0x3d | 0x3d | RETURNDATASIZE | 0 size 0 0 0 // -// 0x73 | 0x73 | PUSH20 | addr 0 size 0 0 0 // - -// AFTER ADDRESS -//--------------------------------------------------------------------------------// -// Opcode | Opcode + Arguments | Description | Stack View // -//--------------------------------------------------------------------------------// -// 0x5a | 0x5a | GAS | gas addr 0 size 0 0 0 // -// 0xf4 | 0xf4 | DELEGATECALL | success 0 // -// 0x3d | 0x3d | RETURNDATASIZE | rds success 0 // -// 0x82 | 0x82 | DUP3 | 0 rds success 0 // -// 0x80 | 0x80 | DUP1 | 0 0 rds success 0 // -// 0x3e | 0x3e | RETURNDATACOPY | success 0 // -// 0x90 | 0x90 | SWAP1 | 0 success // -// 0x3d | 0x3d | RETURNDATASIZE | rds 0 success // -// 0x91 | 0x91 | SWAP2 | success rds 0 // -// 0x60 | 0x602b | PUSH1 0x2b | 0x2b success rds 0 // -// 0x57 | 0x57 | JUMPI | Revert if success == 0 // -// 0xfd | 0xfd | REVERT | // -// 0x5b | 0x5b | JUMPDEST | // -// 0xf3 | 0xf3 | RETURN | // -//--------------------------------------------------------------------------------// - -#define constant BYTECODE_BEFORE_ADDRESS = 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000 -#define constant BYTECODE_AFTER_ADDRESS = 0x5af43d82803e903d91602b57fd5bf3 - -/// @notice Clone a contract using `create`. -/// @param {Stack} Implementation - address of the contract to clone. -#define macro CLONE() = takes (1) returns (1) { - CLONE_MACRO(create) -} - -/// @notice Clone a contract to a deterministic address using `create2`. -/// @param {Stack} Implementation - address of the contract to clone. -/// @param {Stack} Salt - The salt to be added to create2. -#define macro CLONE_DETERMINISTIC() = takes (2) returns (1) { - CLONE_MACRO(create2) -} - -/// @dev Can remain inside the scratch space therefore no memory pointer is required -#define macro CLONE_MACRO(deploy_opcode) = takes (2) returns (1) { - // Input Stack: [implementation, salt [optional]] - - // Store the prefix - __RIGHTPAD(0x3d602d80600a3d3981f3363d3d373d3d3d363d73) // [prefix, implementation, salt] - 0x00 mstore // [implementation, salt] - - // Place the implementation at memory byte 20 - 0x60 shl // [rightpad(implementation), salt] - 0x14 mstore // [salt] - - // Add the suffix after the implementation at byte 40 - __RIGHTPAD(0x5af43d82803e903d91602b57fd5bf3) // [suffix, salt] - 0x28 mstore // [salt] - - // Create the contract - 0x37 // [0x37, salt] - 0x00 // [0x00, 0x37, salt] - 0x00 // [0x00, 0x00, 0x37, salt] - // [address] * This will be create | create2 - - // Throw exception if deployment fails - dup1 iszero create_failed jumpi // [address] - continue jump - - create_failed: - DEPLOYMENT_FAILED(0x00) - - continue: -} - - -/// @dev Memory pointer required as this function nukes memory and this is part of a library -#define macro PREDICT_DETERMINISTIC_ADDRESS(ptr) = takes (3) returns (1) { - // Input Stack: [implementation, salt, deployer] - swap1 swap2 swap1 // [implementation, deployer, salt] - - // Store the creation code prefix at memory byte 0 - __RIGHTPAD(0x3d602d80600a3d3981f3363d3d373d3d3d363d73) // [prefix, implementation, deployer, salt] - mstore // [implementation, deployer, salt] - - // Store the implementation address at memory byte 20 - 0x60 shl // [rightpad(implementation), deployer, salt] - 0x14 add // [ptr + 0x14, implementation, deployer, salt] - mstore // [deployer, salt] - - // Store the creation code suffix at memory byte 40 - __RIGHTPAD(0x5af43d82803e903d91602b57fd5bf3ff) // [bytecode_after, deployer, salt] - 0x28 add // [ptr + 0x28, bytecode_after, deployer, salt] - mstore // [deployer, salt] - - // mstore(add(ptr, 0x38), deployer) - 0x60 shl // [rightpad(deployer), salt] - 0x38 add // [ptr + 0x38, deployer, salt] - mstore // [salt] - - // mstore(add(ptr, 0x58), salt) - 0x4c add // [ptr + 0x58, salt] - mstore // [] - - // Hash and then store in memory - 0x37 // [0x37] - // [ptr, 0x37] - sha3 // [hash] - - 0x6c add // [ptr + 0x6c, hash] - mstore // [] - - // Hash the rest of the data - 0x55 // [0x55] - 0x37 add // [ptr + 0x37, 0x55] - sha3 // [hash] - - // Clean the upper 96 bits (12 bytes) of the hash - // The remaining 160 bits (20 bytes) are the address - 0x60 shl 0x60 shr // [clean(hash)] -} \ No newline at end of file diff --git a/src/proxies/__TEMP__zgifhurblgmhozyfyviczblaggscrgixERC1967Proxy.huff b/src/proxies/__TEMP__zgifhurblgmhozyfyviczblaggscrgixERC1967Proxy.huff deleted file mode 100644 index 63eb9ef3..00000000 --- a/src/proxies/__TEMP__zgifhurblgmhozyfyviczblaggscrgixERC1967Proxy.huff +++ /dev/null @@ -1,158 +0,0 @@ -// Functions -// Implementation -#define function implementation() nonpayable returns (address) -#define function upgradeTo(address) nonpayable returns () -#define function upgradeToAndCall(address,bytes,bool) nonpayable returns () -#define function upgradeToAndCallUUPS(address,bytes,bool) nonpayable returns () - -// Admin -#define function admin() view returns (address) -#define function changeAdmin(address) nonpayable returns () - -// Beacon -#define function beacon() view returns (address) -#define function setBeacon(address) nonpayable returns () -#define function upgradeBeaconAndCall(address,bytes,bool) nonpayable returns () - - -// Implementations -#define macro IMPLEMENTATION_WRAPPER() = { - IMPLEMENTATION() - 0x00 mstore - 0x20 0x00 return -} - -#define macro UPGRADE_TO_WRAPPER() = { - 0x04 calldataload - UPGRADE_TO() - stop -} - -#define macro UPGRADE_TO_AND_CALL_WRAPPER() = { - 0x44 calldataload // [forceCall] - 0x24 calldataload // [data, forceCall] - 0x04 calldataload // [implementation, data, forceCall] - UPGRADE_TO_AND_CALL() - stop -} - -#define macro UPGRADE_TO_AND_CALL_UUPS_WRAPPER() = { - 0x44 calldataload // [forceCall] - 0x24 calldataload // [data, forceCall] - 0x04 calldataload // [implementation, data, forceCall] - UPGRADE_TO_AND_CALL_UUPS() - stop -} - -// Admin -#define macro GET_ADMIN_WRAPPER() = { - GET_ADMIN() - 0x00 mstore - 0x20 0x00 return -} - -#define macro CHANGE_ADMIN_WRAPPER() = { - 0x04 calldataload - CHANGE_ADMIN() - stop -} - - -// Beacon -#define macro GET_BEACON_WRAPPER() = { - GET_BEACON() - 0x00 mstore - 0x20 0x00 return -} - -#define macro SET_BEACON_WRAPPER() = { - 0x04 calldataload - SET_BEACON() - stop -} - -#define macro UPGRADE_BEACON_TO_AND_CALL_WRAPPER() = { - 0x44 calldataload // [forceCall] - 0x24 calldataload // [data, forceCall] - 0x04 calldataload // [implementation, data, forceCall] - UPGRADE_TO_BEACON_AND_CALL() - stop -} - - -// For the sake of this example, the owner will be passed in -#define macro CONSTRUCTOR() = { - // ERC1967_PROXY_CONSTRUCTOR() - - 0x20 - 0x20 codesize sub - 0x00 - codecopy - 0x00 mload - - SET_ADMIN() -} - -#define macro MAIN() = { - pc calldataload 0xe0 shr - - dup1 __FUNC_SIG(implementation) eq implementation jumpi - dup1 __FUNC_SIG(upgradeTo) eq upgradeTo jumpi - dup1 __FUNC_SIG(upgradeToAndCall) eq upgradeToAndCall jumpi - dup1 __FUNC_SIG(upgradeToAndCallUUPS) eq upgradeToAndCallUUPS jumpi - - dup1 __FUNC_SIG(admin) eq getAdmin jumpi - dup1 __FUNC_SIG(changeAdmin) eq changeAdmin jumpi - - dup1 __FUNC_SIG(beacon) eq getBeacon jumpi - dup1 __FUNC_SIG(setBeacon) eq setBeacon jumpi - dup1 __FUNC_SIG(upgradeBeaconAndCall) eq upgradeBeaconAndCall jumpi - - GET_IMPLEMENTATION() // [implementation] - DELEGATE() - - implementation: - IMPLEMENTATION_WRAPPER() - upgradeTo: - UPGRADE_TO_WRAPPER() - upgradeToAndCall: - UPGRADE_TO_AND_CALL_WRAPPER() - upgradeToAndCallUUPS: - UPGRADE_TO_AND_CALL_UUPS_WRAPPER() - - getAdmin: - GET_ADMIN_WRAPPER() - changeAdmin: - CHANGE_ADMIN_WRAPPER() - - getBeacon: - GET_BEACON_WRAPPER() - setBeacon: - SET_BEACON_WRAPPER() - upgradeBeaconAndCall: - UPGRADE_BEACON_TO_AND_CALL_WRAPPER() - -} - -/// @title ERC1967 Proxy -/// @notice SPDX-License-Identifier: MIT -/// @author asnared -/// @notice An upgradeable proxy that uses the ERC1967 storage layout. -/// @notice Adapted from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/proxy/ERC1967/ERC1967Proxy.sol) - -#include "./Proxy.huff" -#include "./ERC1967Upgrade.huff" - -/// @notice An internal constructor that upgrades the proxy to the implementation and calls the implementation -#define macro ERC1967_PROXY_CONSTRUCTOR() = takes (0) returns (0) { - 0x00 // [forceCall] - 0x24 calldataload // [data, forceCall] - 0x04 calldataload // [address, data, forceCall] - UPGRADE_TO_AND_CALL() // [] -} - -/// @notice Returns the current implementation address -/// @notice Overrideable -#define macro IMPLEMENTATION() = takes (0) returns (1) { - GET_IMPLEMENTATION() -} diff --git a/src/tokens/__TEMP__fztznazwowexesrohcdykwsmvfkclmuyERC20.huff b/src/tokens/__TEMP__fztznazwowexesrohcdykwsmvfkclmuyERC20.huff deleted file mode 100644 index 75ecc0af..00000000 --- a/src/tokens/__TEMP__fztznazwowexesrohcdykwsmvfkclmuyERC20.huff +++ /dev/null @@ -1,676 +0,0 @@ - -#define function mint(address, uint256) nonpayable returns () -#define function burn(address, uint256) nonpayable returns () - -#define macro BURN() = takes (0) returns (0) { - NON_PAYABLE() - // Setup the stack for the burn function. - 0x04 calldataload // [from] - 0x24 calldataload // [value, from] - - // Call ERC20.huff's _BURN macro - _BURN() // [] - - // Stop Execution - stop // [] -} - -#define macro MINT() = takes (0) returns (0) { - NON_PAYABLE() - - // Setup the stack for the mint function. - 0x04 calldataload // [to] - 0x24 calldataload // [value, to] - - // Call ERC20.huff's _MINT macro - _MINT() // [] - - // Stop Execution - stop // [] -} - -#define macro CONSTRUCTOR() = takes (0) returns (0) { - ERC20_CONSTRUCTOR() -} - -#define macro MAIN() = takes (0) returns (0) { - 0x00 calldataload 0xE0 shr // [sig] - - dup1 __FUNC_SIG(mint) eq mint jumpi // [sig] - dup1 __FUNC_SIG(burn) eq burn jumpi // [sig] - - ERC20_MAIN() // [sig] - - // Revert if no selector matches - 0x00 0x00 revert - - mint: - MINT() - burn: - BURN() -} - -/// @title ERC20 -/// @notice SPDX-License-Identifier: MIT -/// @author asnared -/// @author devtooligan -/// @notice Modern and gas efficient ERC20 + EIP-2612 implementation -/// @notice Adapted from Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC20.sol) - -// Imports -#include "../utils/Errors.huff" -#include "../auth/NonPayable.huff" -#include "../data-structures/Hashmap.huff" - -// Interface -#define function allowance(address,address) view returns (uint256) -#define function approve(address,uint256) nonpayable returns () -#define function balanceOf(address) view returns (uint256) -#define function DOMAIN_SEPARATOR() view returns (bytes32) -#define function nonces(address) view returns (uint256) -#define function permit(address,address,uint256,uint256,uint8,bytes32,bytes32) nonpayable returns () -#define function totalSupply() view returns (uint256) -#define function transfer(address,uint256) nonpayable returns () -#define function transferFrom(address,address,uint256) nonpayable returns () - -// Events -#define event Approval(address indexed, address indexed, uint256) -#define event Transfer(address, address, uint256) - -// Metadata -#define function decimals() nonpayable returns (uint8) -#define function name() nonpayable returns (string) -#define function symbol() nonpayable returns (string) - -// ERC20 Storage -#define constant TOTAL_SUPPLY_SLOT = FREE_STORAGE_POINTER() -#define constant BALANCE_SLOT = FREE_STORAGE_POINTER() -#define constant APPROVAL_SLOT = FREE_STORAGE_POINTER() - -// EIP-2612 STORAGE -#define constant INITIAL_CHAIN_ID = FREE_STORAGE_POINTER() -#define constant INITIAL_DOMAIN_SEPARATOR = FREE_STORAGE_POINTER() -#define constant NONCE_SLOT = FREE_STORAGE_POINTER() - -// Immutables offsets -#define constant DECIMALS_OFFSET = 0x0000000000000000000000000000000000000000000000000000000000000020 -#define constant NAME_OFFSET = 0x00000000000000000000000000000000000000000000000000000000000000a0 -#define constant NAME_LENGTH_OFFSET = 0x00000000000000000000000000000000000000000000000000000000000000c0 -#define constant SYMBOL_OFFSET = 0x0000000000000000000000000000000000000000000000000000000000000040 -#define constant SYMBOL_LENGTH_OFFSET = 0x0000000000000000000000000000000000000000000000000000000000000060 - -// PERMIT_TYPEHASH = keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)") -#define constant PERMIT_TYPEHASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9 -#define constant X_1901 = 0x1901000000000000000000000000000000000000000000000000000000000000 - -// Utility Constants -#define constant UINT_256_MAX = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -#define constant ERROR_SIG = 0x08c379a000000000000000000000000000000000000000000000000000000000 -#define constant ZERO_ADDRESS = 0x0000000000000000000000000000000000000000 - -/// @notice Constructor -/// @notice Sets the initial domain separator and chain ID -#define macro ERC20_CONSTRUCTOR() = takes (0) returns (0) { - // Constructor arguments: - // ?, name_size, name, ?, symbol_size, symbol, decimals - - // This constructor will return the runtime bytecode with all the - // constructor arguments concatenated at the end. - - chainid [INITIAL_CHAIN_ID] sstore // [] - COMPUTE_DOMAIN_SEPARATOR() // [DOMAIN SEPARATOR] - [INITIAL_DOMAIN_SEPARATOR] sstore // [] - - // Copy the runtime bytecode with constructor argument concatenated. - 0x67 // [offset] - constructor code size - dup1 // [offset, offset] - codesize // [total_size, offset, offset] - sub // [runtime_size, offset] - dup1 // [runtime_size, runtime_size, offset] - swap2 // [offset, runtime_size, runtime_size] - returndatasize // [return_offset, offset, runtime_size, runtime_size] - codecopy // [runtime_size] - - // Return the runtime bytecode. - returndatasize // [return_offset, runtime_size] - return // [] -} - -/// @notice Retrives an "immutable" from the runtime bytecode. -#define macro _GET_IMMUTABLE(offset_end, free_memory) = takes (0) returns (1) { - 0x20 // [size] - codesize sub // [offset_code, size] - // [offset_memory, offset_code, size] - codecopy // [] - mload // [value] -} - -/// @notice Approve -/// @notice Grants approval to an operator to transfer tokens on behalf of the sender. -#define macro APPROVE() = takes (0) returns (0) { - NON_PAYABLE() // [] - - 0x24 calldataload // [value] - 0x04 calldataload // [to, value] - caller // [from, to, value] - [APPROVAL_SLOT] // [slot, from, to, value] - STORE_ELEMENT_FROM_KEYS_2D(0x00) // [] - - // Emit the Approval event - 0x24 calldataload // [value] - 0x00 mstore // [] - 0x04 calldataload // [to] - caller // [from, to] - __EVENT_HASH(Approval) // [sig, from, to] - 0x20 0x00 // [0, 32, sig, from, to] - log3 // [] - - // Return 01 for true - 0x01 0x00 mstore // [] - 0x20 0x00 return // [] -} - -/// @notice Transfer -/// @notice Non-Payable function that transfers an amount of tokens from the sender to a recipient. -#define macro TRANSFER() = takes (0) returns (0) { - NON_PAYABLE() - - // Setup the stack for the transfer function. - 0x04 calldataload // [to] - caller // [from, to] - 0x24 calldataload // [value, from, to] - - // Update the balances of the sender and recipient. - _TRANSFER_TAKE_FROM() // [value, from, to] - _TRANSFER_GIVE_TO() // [value, from, to] - - // Emit the transfer event. - 0x00 mstore // [from, to] - __EVENT_HASH(Transfer) // [sig, from, to] - 0x20 0x00 // [0, 32, sig, from, to] - log3 // [] - - // Return "1" to represent a succesful transfer. - 0x01 0x00 mstore // [] - 0x20 0x00 return // [] -} - -/// @notice Transfer From -/// @notice Non-Payable function that transfers an amount of tokens from an address to a recipient. -#define macro TRANSFER_FROM() = takes (0) returns (0) { - NON_PAYABLE() // [] - - // Setup the stack for the transfer function. - 0x24 calldataload // [to] - 0x04 calldataload // [from, to] - caller // [msg.sender, from, to] - dup2 // [from, msg.sender, from, to] - [APPROVAL_SLOT] // [slot, from, msg.sender, from, to] - - // Check for max approval - LOAD_ELEMENT_FROM_KEYS_2D(0x00) // [approved, from, to] - dup1 // [approved, approved, from, to] - 0x44 calldataload // [value, approved, approved, from, to] - - // Check isOwner - dup4 // [from, value, approved, approved, from, to] - caller // [msg.sender, from, value, approved, approved, from, to] - eq // [msg.sender == from, value, approved, approved, from, to] - approved1 jumpi // [value, approved, approved, from, to] - - // Check max approval - dup2 // [approved, value, approved, approved, from, to] - [UINT_256_MAX] // [type(uint).max, approved, value, approved, approved, from, to] - eq // [type(uint).max == approved, value, approved, approved, from, to] - approved1 jumpi // [value, approved, approved, from, to] - - // Check has approval - gt // [value > approved, approved, from, to] - insufficientApproval jumpi // [approved, from, to] - - // Adjust approval - 0x44 calldataload // [value, approved, from, to] - swap1 // [approved, value, from, to] - sub // [approved - value => newApprovalValue, from, to] - caller // [msg.sender, newApprovalValue, from, to] - dup3 // [from, msg.sender, newApprovalValue, from, to] - [APPROVAL_SLOT] // [slot, from, msg.sender, newApprovalValue, from, to] - STORE_ELEMENT_FROM_KEYS_2D(0x00) // [from, to] - approved2 jump // [from, to] - - approved1: // [value, approved, approved, from, to] - pop pop pop // [from, to] - - approved2: // [from, to] - 0x44 calldataload // [value, from, to] - - // Update the balances of the sender and recipient. - _TRANSFER_TAKE_FROM() // [value, from, to] - _TRANSFER_GIVE_TO() // [value, from, to] - - // Emit the transfer event. - 0x00 mstore // [from, to] - __EVENT_HASH(Transfer) // [sig, from, to] - 0x20 0x00 // [0, 32, sig, from, to] - log3 // [] - - // Return "1" to represent a succesful transfer. - 0x01 0x00 mstore // [] - 0x20 0x00 return // [] - - insufficientApproval: - 0x00 0x00 revert // [] -} - -/// @notice Transfers an amount of tokens from -#define macro _TRANSFER_TAKE_FROM() = takes (3) returns (3) { - // input stack: [value, from, to] - dup2 [BALANCE_SLOT] LOAD_ELEMENT_FROM_KEYS(0x00) // [balance, value, from, to] // [from, value, from, to] - dup1 // [balance, balance, value, from, to] - dup3 // [value, balance, balance, value, from, to] - gt // [value > balance, balance, value, from, to] - iszero // [value <= balance, balance, value, from, to] - valid jumpi // [balance, value, from, to] - - // Insufficient balance - 0x00 0x00 revert // [] - - // Update the sender's balance. - valid: - dup2 // [value, balance, value, from, to] - swap1 // [balance, value, value, from, to] - sub // [balance - value, value, from, to] - dup3 // [from, balance - value, value, from, to] - [BALANCE_SLOT] STORE_ELEMENT_FROM_KEYS(0x00) // [value, from, to] -} - -/// @notice Transfers an amount of tokens from one address to another. -#define macro _TRANSFER_GIVE_TO() = takes (3) returns (3) { - // input stack: [value, from, to] - dup3 // [to, value, from, to] - dup2 // [value, to, value, from, to] - swap1 // [to, value, value, from, to] - [BALANCE_SLOT] LOAD_ELEMENT_FROM_KEYS(0x00) // [balance, value, value, from, to] - add // [balance + value, value, from, to] - dup4 // [to, balance + value, value, from, to] - [BALANCE_SLOT] STORE_ELEMENT_FROM_KEYS(0x00) // [value, from, to] -} - -/// @notice Approve -/// @notice Approves an address to spend an amount of tokens on the caller's behalf -#define macro APPROVE() = takes (0) returns (0) { - 0x24 calldataload // [value] - dup1 0x00 mstore // [value] - 0x04 calldataload // [to, value] - caller // [from, to, value] - - // Emit the approval event. - dup2 dup2 // [from, to, from, to, value] - __EVENT_HASH(APPROVAL_EVENT_SIGNATURE) // [sig, from, to, from, to, value] - 0x20 0x00 // [0, 32, sig, from, to, from, to, value] - log3 // [from, to, value] - - // Store the value at slot = keccak256(from . to) - STORE_ELEMENT_FROM_KEYS(0x00) -} - -/// @notice Domain Separator -/// @notice Returns the EIP-712 domain separator -#define macro DOMAIN_SEPARATOR() = takes (0) returns (0) { - NON_PAYABLE() // [] - _DOMAIN_SEPARATOR() // [domain separator] - 0x00 mstore // [domain separator] - 0x20 0x00 return // [] -} - -/// @notice Loads the EIP-712 domain separator -#define macro _DOMAIN_SEPARATOR() = takes (0) returns (1) { - chainid // [chainid] - [INITIAL_CHAIN_ID] sload // [INITIAL_CHAIN_ID, chainid] - eq // [INITIAL_CHAIN_ID == chainid] - useInitial jumpi // [] - COMPUTE_DOMAIN_SEPARATOR() // [computed domain separator] - done jump - - useInitial: - [INITIAL_DOMAIN_SEPARATOR] sload // [INITIAL_DOMAIN_SEPARATOR] - - done: -} - -/// @notice Computes the EIP-712 domain separator -#define macro COMPUTE_DOMAIN_SEPARATOR() = takes (0) returns (1) { - // WARNING: 0x00 - 0x3f (64 bytes): scratch space for hashing methods - // AS SUCH, WE STORE VARIABLES IN MEMORY STARTING AT 0x40 - - _GET_IMMUTABLE(NAME_OFFSET, 0xd0) // [name] - - [PERMIT_TYPEHASH] 0x40 mstore // [name] - 0x60 mstore // [] - 0x20 0x60 sha3 0x60 mstore // [] - - // 0x31 is hex for ascii for 1 - 0x31 0x80 mstore // [] - 0x02 0x80 sha3 0x80 mstore // [hash of "1"] - - chainid 0xa0 mstore // [chainid] - address 0xc0 mstore // [address(this)] - - 0xA0 0x40 sha3 // [hash] -} - -/// @notice Permit -/// @notice EIP 2612 Signed Approvals -#define macro PERMIT() = takes (0) returns (0) { - NON_PAYABLE() - // function permit arg calldata loc - // address owner 0x04 - // address spender 0x24 - // uint256 value 0x44 - // uint256 deadline 0x64 - // uint8 v 0x84 - // bytes32 r 0xa4 - // bytes32 s 0xc4 - - // check deadline - 0x64 calldataload // [deadline] - dup1 // [deadline, deadline] - timestamp // [timestamp, deadline, deadline] - gt // [timestamp > deadline, deadline] - expired jumpi // [deadline] - - // Calculate inner keccak - // keccak256( - // abi.encode( - // PERMIT_TYPEHASH, - // owner, - // spender, - // value, - // nonces[owner]++, - // deadline - // ) - // ) - 0x04 calldataload // [owner, deadline] - _NONCE_PLUS_PLUS() // [nonce, deadline] - 0x44 calldataload // [value, nonce, deadline] - 0x24 calldataload // [spender, value, nonce, deadline] - 0x04 calldataload // [owner, spender, value, nonce, deadline] - [PERMIT_TYPEHASH] // [permit hash, owner, spender, value, nonce, deadline] - 0x00 mstore // [owner, spender, value, nonce, deadline] - 0x20 mstore // [spender, value, nonce, deadline] - 0x40 mstore // [value, nonce, deadline] - 0x60 mstore // [nonce, deadline] - 0x80 mstore // [deadline] - 0xa0 mstore // [] - 0xc0 0x00 // [loc, len] - sha3 // [inner hash] - - // Grab the domain separator - _DOMAIN_SEPARATOR() // [domain separator, inner hash] - [X_1901] // [x1901, domain separator, inner hash] - - // Bitwise shifts - dup3 0xf0 shl // [inner hash << 0xf0, x1901, domain separator, inner hash] - - // Create the second word - dup3 0xf0 shl // [domain separator << 0xf0, inner hash << 0xf0, x1901, domain separator, inner hash] - dup5 0x10 shr or // [domain separator << 0xf0 | inner hash >> 0x10, inner hash << 0xf0, x1901, domain separator, inner hash] - - // Create the first word - dup4 dup4 swap1 0x10 shr or // [x1901 | domain separator >> 0x10, domain separator << 0xf0 | inner hash >> 0x10, inner hash << 0xf0, x1901, domain separator, inner hash] - - // Prepare memory mstore outer keccak - 0x40 mstore // [domain separator << 0xf0 | inner hash >> 0x10, inner hash << 0xf0, x1901, domain separator, inner hash] - 0x60 mstore // [inner hash << 0xf0, x1901, domain separator, inner hash] - 0x80 mstore // [x1901, domain separator, inner hash] - 0x42 0x40 // [loc, len, x1901, domain separator, inner hash] - sha3 // [outer hash, x1901, domain separator, inner hash] - - // Store signature in memory memory layout: - 0x00 mstore // [] 0x00 outer hash - 0x84 calldataload // [v] - 0x20 mstore // [] 0x00 outerhash 0x20 v - 0xa4 calldataload // [r] - 0x40 mstore // [] 0x00 outerhash 0x20 v 0x40 r - 0xc4 calldataload // [s] - 0x60 mstore // [] 0x00 outerhash 0x20 v 0x40 r 0x60 s - - // Prepare stack for later - 0x44 calldataload // [value] - 0x24 calldataload // [spender, value] - - // ecrecover - 0x20 // [32, spender, value] - 0x80 // [128, 32, spender, value] - 0x80 // [128, 128, 32, spender, value] - 0x00 // [0, 128, 128, 32, spender, value] - 0x1 // [ecrecover precompile address, 0, 128, 128, 32, spender, value] - 0xFFFFFFFF // [gas, ecrecover precompile address, 0, 128, 128, 32, spender, value] - staticcall // [success, spender, value] - - // Revert invalid signer if call failed - iszero invalidSigner jumpi // [spender, value] - - // Load the recovered address from memory - 0x80 mload // [recovered address, spender, value] - - // check for recovered 0 address - dup1 // [recovered address, recovered address, spender, value] - 0x00 eq // [recovered address == 0, recovered address, spender, value] - invalidSigner jumpi // [recovered address, spender, value] - - // check for address is owner - dup1 // [recovered address, recovered address, spender, value] - 0x04 calldataload // [owner, recovered address, recovered address, spender, value] - eq // [owner == recovered address, recovered address, spender, value] - iszero // [owner != recovered address, recovered address, spender, value] - invalidSigner jumpi // [recovered address, spender, value] - [APPROVAL_SLOT] // [slot, recovered address, spender, value] - STORE_ELEMENT_FROM_KEYS_2D(0x00) // [] - - // Emit the Approval event - 0x44 calldataload // [value] - 0x00 mstore // [] - 0x24 calldataload // [to] - 0x04 calldataload // [from, to] - __EVENT_HASH(Approval) // [sig, from, to] - 0x20 0x00 // [0, 32, sig, from, to] - log3 // [] - - // Stop Execution - stop // [] - - expired: - 0x5045524D49545F444541444C494E455F45585049524544000000000000000000 // ["PERMIT_DEADLINE_EXPIRED"] - 0x17 // [23 (length), "PERMIT_DEADLINE_EXPIRED"] - 0x00 // [0, 23 (length), "PERMIT_DEADLINE_EXPIRED"] - REQUIRE() - - invalidSigner: - 0x494E56414C49445F5349474E4552000000000000000000000000000000000000 // ["INVALID_SIGNER"] - 0x0e // [14 (length), "INVALID_SIGNER"] - 0x00 // [0, 14 (length), "INVALID_SIGNER"] - REQUIRE() -} - -/// @notice Takes an address off the stack, returns the current nonce for that address onto the stack. -/// @notice Increments the nonce for next time, -#define macro _NONCE_PLUS_PLUS() = takes (1) returns (1) { - // input stack // [account] - dup1 // [account, account] - [NONCE_SLOT] LOAD_ELEMENT_FROM_KEYS(0x00) // [currentNonce, account] - dup1 // [currentNonce, currentNonce, account] - 0x01 // [1, currentNonce, currentNonce, account] - add // [nextNonce, currentNonce, account] - dup3 // [account, nextNonce, currentNonce, account] - [NONCE_SLOT] STORE_ELEMENT_FROM_KEYS(0x00) // [currentNonce, account] - swap1 // clean up stack // [account, currentNonce] - pop // clean up stack // [currentNonce] -} - -/// @notice Nonces -/// @notice Returns the current nonce for an account -#define macro NONCES() = takes (0) returns (0) { - 0x04 calldataload // [account] - [NONCE_SLOT] LOAD_ELEMENT_FROM_KEYS(0x00) // [nonce] - 0x00 mstore // [] - 0x20 0x00 return // [] -} - -/// @notice Name -/// @notice Returns the token name string -#define macro NAME() = takes (0) returns (0) { - NON_PAYABLE() // [] - _GET_IMMUTABLE(NAME_OFFSET, 0x00) // [name_value] - _GET_IMMUTABLE(NAME_LENGTH_OFFSET, 0x00) // [name_length, name_value] - 0x20 0x00 mstore // [name_length, name_value] - 0x20 mstore // [name_value] - 0x40 mstore // [] - 0x60 0x00 return // [] -} - -/// @notice Symbol -/// @notice Returns the symbol of the token -#define macro SYMBOL() = takes (0) returns (0) { - NON_PAYABLE() // [] - _GET_IMMUTABLE(SYMBOL_OFFSET, 0x00) // [symbol_value] - _GET_IMMUTABLE(SYMBOL_LENGTH_OFFSET, 0x00) // [symbol_length, symbol_value] - 0x20 0x00 mstore // [symbol_length, symbol_value] - 0x20 mstore // [symbol_value] - 0x40 mstore // [] - 0x60 0x00 return // [] -} - -/// @notice Decimals -/// @notice Returns the token decimal representation -#define macro DECIMALS() = takes (0) returns (0) { - NON_PAYABLE() // [] - _GET_IMMUTABLE(DECIMALS_OFFSET, 0x00) // [decimals] - 0x00 mstore // [] - 0x20 0x00 return // [] -} - -/// @notice Balance Of -/// @notice Returns the token balance of an address -#define macro BALANCE_OF() = takes (0) returns (0) { - NON_PAYABLE() // [] - 0x04 calldataload // [account] - [BALANCE_SLOT] LOAD_ELEMENT_FROM_KEYS(0x00) // [balance] - 0x00 mstore // [] - 0x20 0x00 return // [] -} - -/// @notice Total Supply -/// @notice Returns the total supply of the token -#define macro TOTAL_SUPPLY() = takes (0) returns (0) { - NON_PAYABLE() // [] - [TOTAL_SUPPLY_SLOT] sload // [supply] - 0x00 mstore // [] - 0x20 0x00 return // [] -} - -/// @notice Allowance -/// @notice Returns the amount which a spender is allowed to transfer on behalf of an owner -#define macro ALLOWANCE() = takes (0) returns (0) { - NON_PAYABLE() // [] - 0x24 calldataload // [to] - 0x04 calldataload // [from, to] - [APPROVAL_SLOT] // [slot, from, to] - LOAD_ELEMENT_FROM_KEYS_2D(0x00) // [allowance] - 0x00 mstore // [] - 0x20 0x00 return // [] -} - -// MINT/BURN LOGIC - -#define macro _BURN() = takes(2) returns (0) { - // stack input: [value, from] - [ZERO_ADDRESS] // [zero, value, from] - swap2 swap1 // [value, from, zero] - - _TRANSFER_TAKE_FROM() // [value, from, zero] - dup1 // [value, value, from, zero] - [TOTAL_SUPPLY_SLOT] sload // [supply, value, value, from, zero] - sub // [supply-value, value, from, zero] - [TOTAL_SUPPLY_SLOT] sstore // [value, from, zero] - - // Emit the transfer event. - 0x00 mstore // [from, zero] - __EVENT_HASH(Transfer) // [sig, from, zero] - 0x20 0x00 // [0, 32, sig, from, zero] - log3 // [] -} - -/// @notice Mints tokens to a specified address -#define macro _MINT() = takes (2) returns (0) { - // Input stack: [value, to] - dup2 // [to, value, to] - swap1 // [value, to, to] - _TRANSFER_GIVE_TO() // [value, to, to] - - // Update totalSupply - dup1 // [value, value, to, to] - [TOTAL_SUPPLY_SLOT] sload // [supply, value, value, to, to] - add // [supply + value, value, to, to] - [TOTAL_SUPPLY_SLOT] sstore // [value, to, to] - - // Emit the transfer event. - 0x00 mstore // [to, to] - [ZERO_ADDRESS] // [address(0), to, to] - __EVENT_HASH(Transfer) // [sig, from, to, to] - 0x20 0x00 // [0, 32, sig, from, to, to] - log3 pop // [] -} - - -// Function Dispatching -#define macro ERC20_MAIN() = takes (1) returns (1) { - // Identify which function is being called. - // [func sig] - - dup1 __FUNC_SIG(permit) eq permitJump jumpi - dup1 __FUNC_SIG(nonces) eq noncesJump jumpi - - dup1 __FUNC_SIG(name) eq nameJump jumpi - dup1 __FUNC_SIG(symbol) eq symbolJump jumpi - dup1 __FUNC_SIG(decimals) eq decimalsJump jumpi - dup1 __FUNC_SIG(DOMAIN_SEPARATOR) eq domainSeparatorJump jumpi - - dup1 __FUNC_SIG(totalSupply) eq totalSupplyJump jumpi - dup1 __FUNC_SIG(balanceOf) eq balanceOfJump jumpi - dup1 __FUNC_SIG(allowance) eq allowanceJump jumpi - - dup1 __FUNC_SIG(transfer) eq transferJump jumpi - dup1 __FUNC_SIG(transferFrom) eq transferFromJump jumpi - dup1 __FUNC_SIG(approve) eq approveJump jumpi - - // Bubble up to the parent macro - no_match jump - - allowanceJump: - ALLOWANCE() - approveJump: - APPROVE() - balanceOfJump: - BALANCE_OF() - decimalsJump: - DECIMALS() - domainSeparatorJump: - DOMAIN_SEPARATOR() - nameJump: - NAME() - noncesJump: - NONCES() - permitJump: - PERMIT() - symbolJump: - SYMBOL() - totalSupplyJump: - TOTAL_SUPPLY() - transferFromJump: - TRANSFER_FROM() - transferJump: - TRANSFER() - - no_match: -} diff --git a/src/tokens/__TEMP__olyemymwzenpqjpuukwgitehudafctpwERC20.huff b/src/tokens/__TEMP__olyemymwzenpqjpuukwgitehudafctpwERC20.huff deleted file mode 100644 index 75ecc0af..00000000 --- a/src/tokens/__TEMP__olyemymwzenpqjpuukwgitehudafctpwERC20.huff +++ /dev/null @@ -1,676 +0,0 @@ - -#define function mint(address, uint256) nonpayable returns () -#define function burn(address, uint256) nonpayable returns () - -#define macro BURN() = takes (0) returns (0) { - NON_PAYABLE() - // Setup the stack for the burn function. - 0x04 calldataload // [from] - 0x24 calldataload // [value, from] - - // Call ERC20.huff's _BURN macro - _BURN() // [] - - // Stop Execution - stop // [] -} - -#define macro MINT() = takes (0) returns (0) { - NON_PAYABLE() - - // Setup the stack for the mint function. - 0x04 calldataload // [to] - 0x24 calldataload // [value, to] - - // Call ERC20.huff's _MINT macro - _MINT() // [] - - // Stop Execution - stop // [] -} - -#define macro CONSTRUCTOR() = takes (0) returns (0) { - ERC20_CONSTRUCTOR() -} - -#define macro MAIN() = takes (0) returns (0) { - 0x00 calldataload 0xE0 shr // [sig] - - dup1 __FUNC_SIG(mint) eq mint jumpi // [sig] - dup1 __FUNC_SIG(burn) eq burn jumpi // [sig] - - ERC20_MAIN() // [sig] - - // Revert if no selector matches - 0x00 0x00 revert - - mint: - MINT() - burn: - BURN() -} - -/// @title ERC20 -/// @notice SPDX-License-Identifier: MIT -/// @author asnared -/// @author devtooligan -/// @notice Modern and gas efficient ERC20 + EIP-2612 implementation -/// @notice Adapted from Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC20.sol) - -// Imports -#include "../utils/Errors.huff" -#include "../auth/NonPayable.huff" -#include "../data-structures/Hashmap.huff" - -// Interface -#define function allowance(address,address) view returns (uint256) -#define function approve(address,uint256) nonpayable returns () -#define function balanceOf(address) view returns (uint256) -#define function DOMAIN_SEPARATOR() view returns (bytes32) -#define function nonces(address) view returns (uint256) -#define function permit(address,address,uint256,uint256,uint8,bytes32,bytes32) nonpayable returns () -#define function totalSupply() view returns (uint256) -#define function transfer(address,uint256) nonpayable returns () -#define function transferFrom(address,address,uint256) nonpayable returns () - -// Events -#define event Approval(address indexed, address indexed, uint256) -#define event Transfer(address, address, uint256) - -// Metadata -#define function decimals() nonpayable returns (uint8) -#define function name() nonpayable returns (string) -#define function symbol() nonpayable returns (string) - -// ERC20 Storage -#define constant TOTAL_SUPPLY_SLOT = FREE_STORAGE_POINTER() -#define constant BALANCE_SLOT = FREE_STORAGE_POINTER() -#define constant APPROVAL_SLOT = FREE_STORAGE_POINTER() - -// EIP-2612 STORAGE -#define constant INITIAL_CHAIN_ID = FREE_STORAGE_POINTER() -#define constant INITIAL_DOMAIN_SEPARATOR = FREE_STORAGE_POINTER() -#define constant NONCE_SLOT = FREE_STORAGE_POINTER() - -// Immutables offsets -#define constant DECIMALS_OFFSET = 0x0000000000000000000000000000000000000000000000000000000000000020 -#define constant NAME_OFFSET = 0x00000000000000000000000000000000000000000000000000000000000000a0 -#define constant NAME_LENGTH_OFFSET = 0x00000000000000000000000000000000000000000000000000000000000000c0 -#define constant SYMBOL_OFFSET = 0x0000000000000000000000000000000000000000000000000000000000000040 -#define constant SYMBOL_LENGTH_OFFSET = 0x0000000000000000000000000000000000000000000000000000000000000060 - -// PERMIT_TYPEHASH = keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)") -#define constant PERMIT_TYPEHASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9 -#define constant X_1901 = 0x1901000000000000000000000000000000000000000000000000000000000000 - -// Utility Constants -#define constant UINT_256_MAX = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -#define constant ERROR_SIG = 0x08c379a000000000000000000000000000000000000000000000000000000000 -#define constant ZERO_ADDRESS = 0x0000000000000000000000000000000000000000 - -/// @notice Constructor -/// @notice Sets the initial domain separator and chain ID -#define macro ERC20_CONSTRUCTOR() = takes (0) returns (0) { - // Constructor arguments: - // ?, name_size, name, ?, symbol_size, symbol, decimals - - // This constructor will return the runtime bytecode with all the - // constructor arguments concatenated at the end. - - chainid [INITIAL_CHAIN_ID] sstore // [] - COMPUTE_DOMAIN_SEPARATOR() // [DOMAIN SEPARATOR] - [INITIAL_DOMAIN_SEPARATOR] sstore // [] - - // Copy the runtime bytecode with constructor argument concatenated. - 0x67 // [offset] - constructor code size - dup1 // [offset, offset] - codesize // [total_size, offset, offset] - sub // [runtime_size, offset] - dup1 // [runtime_size, runtime_size, offset] - swap2 // [offset, runtime_size, runtime_size] - returndatasize // [return_offset, offset, runtime_size, runtime_size] - codecopy // [runtime_size] - - // Return the runtime bytecode. - returndatasize // [return_offset, runtime_size] - return // [] -} - -/// @notice Retrives an "immutable" from the runtime bytecode. -#define macro _GET_IMMUTABLE(offset_end, free_memory) = takes (0) returns (1) { - 0x20 // [size] - codesize sub // [offset_code, size] - // [offset_memory, offset_code, size] - codecopy // [] - mload // [value] -} - -/// @notice Approve -/// @notice Grants approval to an operator to transfer tokens on behalf of the sender. -#define macro APPROVE() = takes (0) returns (0) { - NON_PAYABLE() // [] - - 0x24 calldataload // [value] - 0x04 calldataload // [to, value] - caller // [from, to, value] - [APPROVAL_SLOT] // [slot, from, to, value] - STORE_ELEMENT_FROM_KEYS_2D(0x00) // [] - - // Emit the Approval event - 0x24 calldataload // [value] - 0x00 mstore // [] - 0x04 calldataload // [to] - caller // [from, to] - __EVENT_HASH(Approval) // [sig, from, to] - 0x20 0x00 // [0, 32, sig, from, to] - log3 // [] - - // Return 01 for true - 0x01 0x00 mstore // [] - 0x20 0x00 return // [] -} - -/// @notice Transfer -/// @notice Non-Payable function that transfers an amount of tokens from the sender to a recipient. -#define macro TRANSFER() = takes (0) returns (0) { - NON_PAYABLE() - - // Setup the stack for the transfer function. - 0x04 calldataload // [to] - caller // [from, to] - 0x24 calldataload // [value, from, to] - - // Update the balances of the sender and recipient. - _TRANSFER_TAKE_FROM() // [value, from, to] - _TRANSFER_GIVE_TO() // [value, from, to] - - // Emit the transfer event. - 0x00 mstore // [from, to] - __EVENT_HASH(Transfer) // [sig, from, to] - 0x20 0x00 // [0, 32, sig, from, to] - log3 // [] - - // Return "1" to represent a succesful transfer. - 0x01 0x00 mstore // [] - 0x20 0x00 return // [] -} - -/// @notice Transfer From -/// @notice Non-Payable function that transfers an amount of tokens from an address to a recipient. -#define macro TRANSFER_FROM() = takes (0) returns (0) { - NON_PAYABLE() // [] - - // Setup the stack for the transfer function. - 0x24 calldataload // [to] - 0x04 calldataload // [from, to] - caller // [msg.sender, from, to] - dup2 // [from, msg.sender, from, to] - [APPROVAL_SLOT] // [slot, from, msg.sender, from, to] - - // Check for max approval - LOAD_ELEMENT_FROM_KEYS_2D(0x00) // [approved, from, to] - dup1 // [approved, approved, from, to] - 0x44 calldataload // [value, approved, approved, from, to] - - // Check isOwner - dup4 // [from, value, approved, approved, from, to] - caller // [msg.sender, from, value, approved, approved, from, to] - eq // [msg.sender == from, value, approved, approved, from, to] - approved1 jumpi // [value, approved, approved, from, to] - - // Check max approval - dup2 // [approved, value, approved, approved, from, to] - [UINT_256_MAX] // [type(uint).max, approved, value, approved, approved, from, to] - eq // [type(uint).max == approved, value, approved, approved, from, to] - approved1 jumpi // [value, approved, approved, from, to] - - // Check has approval - gt // [value > approved, approved, from, to] - insufficientApproval jumpi // [approved, from, to] - - // Adjust approval - 0x44 calldataload // [value, approved, from, to] - swap1 // [approved, value, from, to] - sub // [approved - value => newApprovalValue, from, to] - caller // [msg.sender, newApprovalValue, from, to] - dup3 // [from, msg.sender, newApprovalValue, from, to] - [APPROVAL_SLOT] // [slot, from, msg.sender, newApprovalValue, from, to] - STORE_ELEMENT_FROM_KEYS_2D(0x00) // [from, to] - approved2 jump // [from, to] - - approved1: // [value, approved, approved, from, to] - pop pop pop // [from, to] - - approved2: // [from, to] - 0x44 calldataload // [value, from, to] - - // Update the balances of the sender and recipient. - _TRANSFER_TAKE_FROM() // [value, from, to] - _TRANSFER_GIVE_TO() // [value, from, to] - - // Emit the transfer event. - 0x00 mstore // [from, to] - __EVENT_HASH(Transfer) // [sig, from, to] - 0x20 0x00 // [0, 32, sig, from, to] - log3 // [] - - // Return "1" to represent a succesful transfer. - 0x01 0x00 mstore // [] - 0x20 0x00 return // [] - - insufficientApproval: - 0x00 0x00 revert // [] -} - -/// @notice Transfers an amount of tokens from -#define macro _TRANSFER_TAKE_FROM() = takes (3) returns (3) { - // input stack: [value, from, to] - dup2 [BALANCE_SLOT] LOAD_ELEMENT_FROM_KEYS(0x00) // [balance, value, from, to] // [from, value, from, to] - dup1 // [balance, balance, value, from, to] - dup3 // [value, balance, balance, value, from, to] - gt // [value > balance, balance, value, from, to] - iszero // [value <= balance, balance, value, from, to] - valid jumpi // [balance, value, from, to] - - // Insufficient balance - 0x00 0x00 revert // [] - - // Update the sender's balance. - valid: - dup2 // [value, balance, value, from, to] - swap1 // [balance, value, value, from, to] - sub // [balance - value, value, from, to] - dup3 // [from, balance - value, value, from, to] - [BALANCE_SLOT] STORE_ELEMENT_FROM_KEYS(0x00) // [value, from, to] -} - -/// @notice Transfers an amount of tokens from one address to another. -#define macro _TRANSFER_GIVE_TO() = takes (3) returns (3) { - // input stack: [value, from, to] - dup3 // [to, value, from, to] - dup2 // [value, to, value, from, to] - swap1 // [to, value, value, from, to] - [BALANCE_SLOT] LOAD_ELEMENT_FROM_KEYS(0x00) // [balance, value, value, from, to] - add // [balance + value, value, from, to] - dup4 // [to, balance + value, value, from, to] - [BALANCE_SLOT] STORE_ELEMENT_FROM_KEYS(0x00) // [value, from, to] -} - -/// @notice Approve -/// @notice Approves an address to spend an amount of tokens on the caller's behalf -#define macro APPROVE() = takes (0) returns (0) { - 0x24 calldataload // [value] - dup1 0x00 mstore // [value] - 0x04 calldataload // [to, value] - caller // [from, to, value] - - // Emit the approval event. - dup2 dup2 // [from, to, from, to, value] - __EVENT_HASH(APPROVAL_EVENT_SIGNATURE) // [sig, from, to, from, to, value] - 0x20 0x00 // [0, 32, sig, from, to, from, to, value] - log3 // [from, to, value] - - // Store the value at slot = keccak256(from . to) - STORE_ELEMENT_FROM_KEYS(0x00) -} - -/// @notice Domain Separator -/// @notice Returns the EIP-712 domain separator -#define macro DOMAIN_SEPARATOR() = takes (0) returns (0) { - NON_PAYABLE() // [] - _DOMAIN_SEPARATOR() // [domain separator] - 0x00 mstore // [domain separator] - 0x20 0x00 return // [] -} - -/// @notice Loads the EIP-712 domain separator -#define macro _DOMAIN_SEPARATOR() = takes (0) returns (1) { - chainid // [chainid] - [INITIAL_CHAIN_ID] sload // [INITIAL_CHAIN_ID, chainid] - eq // [INITIAL_CHAIN_ID == chainid] - useInitial jumpi // [] - COMPUTE_DOMAIN_SEPARATOR() // [computed domain separator] - done jump - - useInitial: - [INITIAL_DOMAIN_SEPARATOR] sload // [INITIAL_DOMAIN_SEPARATOR] - - done: -} - -/// @notice Computes the EIP-712 domain separator -#define macro COMPUTE_DOMAIN_SEPARATOR() = takes (0) returns (1) { - // WARNING: 0x00 - 0x3f (64 bytes): scratch space for hashing methods - // AS SUCH, WE STORE VARIABLES IN MEMORY STARTING AT 0x40 - - _GET_IMMUTABLE(NAME_OFFSET, 0xd0) // [name] - - [PERMIT_TYPEHASH] 0x40 mstore // [name] - 0x60 mstore // [] - 0x20 0x60 sha3 0x60 mstore // [] - - // 0x31 is hex for ascii for 1 - 0x31 0x80 mstore // [] - 0x02 0x80 sha3 0x80 mstore // [hash of "1"] - - chainid 0xa0 mstore // [chainid] - address 0xc0 mstore // [address(this)] - - 0xA0 0x40 sha3 // [hash] -} - -/// @notice Permit -/// @notice EIP 2612 Signed Approvals -#define macro PERMIT() = takes (0) returns (0) { - NON_PAYABLE() - // function permit arg calldata loc - // address owner 0x04 - // address spender 0x24 - // uint256 value 0x44 - // uint256 deadline 0x64 - // uint8 v 0x84 - // bytes32 r 0xa4 - // bytes32 s 0xc4 - - // check deadline - 0x64 calldataload // [deadline] - dup1 // [deadline, deadline] - timestamp // [timestamp, deadline, deadline] - gt // [timestamp > deadline, deadline] - expired jumpi // [deadline] - - // Calculate inner keccak - // keccak256( - // abi.encode( - // PERMIT_TYPEHASH, - // owner, - // spender, - // value, - // nonces[owner]++, - // deadline - // ) - // ) - 0x04 calldataload // [owner, deadline] - _NONCE_PLUS_PLUS() // [nonce, deadline] - 0x44 calldataload // [value, nonce, deadline] - 0x24 calldataload // [spender, value, nonce, deadline] - 0x04 calldataload // [owner, spender, value, nonce, deadline] - [PERMIT_TYPEHASH] // [permit hash, owner, spender, value, nonce, deadline] - 0x00 mstore // [owner, spender, value, nonce, deadline] - 0x20 mstore // [spender, value, nonce, deadline] - 0x40 mstore // [value, nonce, deadline] - 0x60 mstore // [nonce, deadline] - 0x80 mstore // [deadline] - 0xa0 mstore // [] - 0xc0 0x00 // [loc, len] - sha3 // [inner hash] - - // Grab the domain separator - _DOMAIN_SEPARATOR() // [domain separator, inner hash] - [X_1901] // [x1901, domain separator, inner hash] - - // Bitwise shifts - dup3 0xf0 shl // [inner hash << 0xf0, x1901, domain separator, inner hash] - - // Create the second word - dup3 0xf0 shl // [domain separator << 0xf0, inner hash << 0xf0, x1901, domain separator, inner hash] - dup5 0x10 shr or // [domain separator << 0xf0 | inner hash >> 0x10, inner hash << 0xf0, x1901, domain separator, inner hash] - - // Create the first word - dup4 dup4 swap1 0x10 shr or // [x1901 | domain separator >> 0x10, domain separator << 0xf0 | inner hash >> 0x10, inner hash << 0xf0, x1901, domain separator, inner hash] - - // Prepare memory mstore outer keccak - 0x40 mstore // [domain separator << 0xf0 | inner hash >> 0x10, inner hash << 0xf0, x1901, domain separator, inner hash] - 0x60 mstore // [inner hash << 0xf0, x1901, domain separator, inner hash] - 0x80 mstore // [x1901, domain separator, inner hash] - 0x42 0x40 // [loc, len, x1901, domain separator, inner hash] - sha3 // [outer hash, x1901, domain separator, inner hash] - - // Store signature in memory memory layout: - 0x00 mstore // [] 0x00 outer hash - 0x84 calldataload // [v] - 0x20 mstore // [] 0x00 outerhash 0x20 v - 0xa4 calldataload // [r] - 0x40 mstore // [] 0x00 outerhash 0x20 v 0x40 r - 0xc4 calldataload // [s] - 0x60 mstore // [] 0x00 outerhash 0x20 v 0x40 r 0x60 s - - // Prepare stack for later - 0x44 calldataload // [value] - 0x24 calldataload // [spender, value] - - // ecrecover - 0x20 // [32, spender, value] - 0x80 // [128, 32, spender, value] - 0x80 // [128, 128, 32, spender, value] - 0x00 // [0, 128, 128, 32, spender, value] - 0x1 // [ecrecover precompile address, 0, 128, 128, 32, spender, value] - 0xFFFFFFFF // [gas, ecrecover precompile address, 0, 128, 128, 32, spender, value] - staticcall // [success, spender, value] - - // Revert invalid signer if call failed - iszero invalidSigner jumpi // [spender, value] - - // Load the recovered address from memory - 0x80 mload // [recovered address, spender, value] - - // check for recovered 0 address - dup1 // [recovered address, recovered address, spender, value] - 0x00 eq // [recovered address == 0, recovered address, spender, value] - invalidSigner jumpi // [recovered address, spender, value] - - // check for address is owner - dup1 // [recovered address, recovered address, spender, value] - 0x04 calldataload // [owner, recovered address, recovered address, spender, value] - eq // [owner == recovered address, recovered address, spender, value] - iszero // [owner != recovered address, recovered address, spender, value] - invalidSigner jumpi // [recovered address, spender, value] - [APPROVAL_SLOT] // [slot, recovered address, spender, value] - STORE_ELEMENT_FROM_KEYS_2D(0x00) // [] - - // Emit the Approval event - 0x44 calldataload // [value] - 0x00 mstore // [] - 0x24 calldataload // [to] - 0x04 calldataload // [from, to] - __EVENT_HASH(Approval) // [sig, from, to] - 0x20 0x00 // [0, 32, sig, from, to] - log3 // [] - - // Stop Execution - stop // [] - - expired: - 0x5045524D49545F444541444C494E455F45585049524544000000000000000000 // ["PERMIT_DEADLINE_EXPIRED"] - 0x17 // [23 (length), "PERMIT_DEADLINE_EXPIRED"] - 0x00 // [0, 23 (length), "PERMIT_DEADLINE_EXPIRED"] - REQUIRE() - - invalidSigner: - 0x494E56414C49445F5349474E4552000000000000000000000000000000000000 // ["INVALID_SIGNER"] - 0x0e // [14 (length), "INVALID_SIGNER"] - 0x00 // [0, 14 (length), "INVALID_SIGNER"] - REQUIRE() -} - -/// @notice Takes an address off the stack, returns the current nonce for that address onto the stack. -/// @notice Increments the nonce for next time, -#define macro _NONCE_PLUS_PLUS() = takes (1) returns (1) { - // input stack // [account] - dup1 // [account, account] - [NONCE_SLOT] LOAD_ELEMENT_FROM_KEYS(0x00) // [currentNonce, account] - dup1 // [currentNonce, currentNonce, account] - 0x01 // [1, currentNonce, currentNonce, account] - add // [nextNonce, currentNonce, account] - dup3 // [account, nextNonce, currentNonce, account] - [NONCE_SLOT] STORE_ELEMENT_FROM_KEYS(0x00) // [currentNonce, account] - swap1 // clean up stack // [account, currentNonce] - pop // clean up stack // [currentNonce] -} - -/// @notice Nonces -/// @notice Returns the current nonce for an account -#define macro NONCES() = takes (0) returns (0) { - 0x04 calldataload // [account] - [NONCE_SLOT] LOAD_ELEMENT_FROM_KEYS(0x00) // [nonce] - 0x00 mstore // [] - 0x20 0x00 return // [] -} - -/// @notice Name -/// @notice Returns the token name string -#define macro NAME() = takes (0) returns (0) { - NON_PAYABLE() // [] - _GET_IMMUTABLE(NAME_OFFSET, 0x00) // [name_value] - _GET_IMMUTABLE(NAME_LENGTH_OFFSET, 0x00) // [name_length, name_value] - 0x20 0x00 mstore // [name_length, name_value] - 0x20 mstore // [name_value] - 0x40 mstore // [] - 0x60 0x00 return // [] -} - -/// @notice Symbol -/// @notice Returns the symbol of the token -#define macro SYMBOL() = takes (0) returns (0) { - NON_PAYABLE() // [] - _GET_IMMUTABLE(SYMBOL_OFFSET, 0x00) // [symbol_value] - _GET_IMMUTABLE(SYMBOL_LENGTH_OFFSET, 0x00) // [symbol_length, symbol_value] - 0x20 0x00 mstore // [symbol_length, symbol_value] - 0x20 mstore // [symbol_value] - 0x40 mstore // [] - 0x60 0x00 return // [] -} - -/// @notice Decimals -/// @notice Returns the token decimal representation -#define macro DECIMALS() = takes (0) returns (0) { - NON_PAYABLE() // [] - _GET_IMMUTABLE(DECIMALS_OFFSET, 0x00) // [decimals] - 0x00 mstore // [] - 0x20 0x00 return // [] -} - -/// @notice Balance Of -/// @notice Returns the token balance of an address -#define macro BALANCE_OF() = takes (0) returns (0) { - NON_PAYABLE() // [] - 0x04 calldataload // [account] - [BALANCE_SLOT] LOAD_ELEMENT_FROM_KEYS(0x00) // [balance] - 0x00 mstore // [] - 0x20 0x00 return // [] -} - -/// @notice Total Supply -/// @notice Returns the total supply of the token -#define macro TOTAL_SUPPLY() = takes (0) returns (0) { - NON_PAYABLE() // [] - [TOTAL_SUPPLY_SLOT] sload // [supply] - 0x00 mstore // [] - 0x20 0x00 return // [] -} - -/// @notice Allowance -/// @notice Returns the amount which a spender is allowed to transfer on behalf of an owner -#define macro ALLOWANCE() = takes (0) returns (0) { - NON_PAYABLE() // [] - 0x24 calldataload // [to] - 0x04 calldataload // [from, to] - [APPROVAL_SLOT] // [slot, from, to] - LOAD_ELEMENT_FROM_KEYS_2D(0x00) // [allowance] - 0x00 mstore // [] - 0x20 0x00 return // [] -} - -// MINT/BURN LOGIC - -#define macro _BURN() = takes(2) returns (0) { - // stack input: [value, from] - [ZERO_ADDRESS] // [zero, value, from] - swap2 swap1 // [value, from, zero] - - _TRANSFER_TAKE_FROM() // [value, from, zero] - dup1 // [value, value, from, zero] - [TOTAL_SUPPLY_SLOT] sload // [supply, value, value, from, zero] - sub // [supply-value, value, from, zero] - [TOTAL_SUPPLY_SLOT] sstore // [value, from, zero] - - // Emit the transfer event. - 0x00 mstore // [from, zero] - __EVENT_HASH(Transfer) // [sig, from, zero] - 0x20 0x00 // [0, 32, sig, from, zero] - log3 // [] -} - -/// @notice Mints tokens to a specified address -#define macro _MINT() = takes (2) returns (0) { - // Input stack: [value, to] - dup2 // [to, value, to] - swap1 // [value, to, to] - _TRANSFER_GIVE_TO() // [value, to, to] - - // Update totalSupply - dup1 // [value, value, to, to] - [TOTAL_SUPPLY_SLOT] sload // [supply, value, value, to, to] - add // [supply + value, value, to, to] - [TOTAL_SUPPLY_SLOT] sstore // [value, to, to] - - // Emit the transfer event. - 0x00 mstore // [to, to] - [ZERO_ADDRESS] // [address(0), to, to] - __EVENT_HASH(Transfer) // [sig, from, to, to] - 0x20 0x00 // [0, 32, sig, from, to, to] - log3 pop // [] -} - - -// Function Dispatching -#define macro ERC20_MAIN() = takes (1) returns (1) { - // Identify which function is being called. - // [func sig] - - dup1 __FUNC_SIG(permit) eq permitJump jumpi - dup1 __FUNC_SIG(nonces) eq noncesJump jumpi - - dup1 __FUNC_SIG(name) eq nameJump jumpi - dup1 __FUNC_SIG(symbol) eq symbolJump jumpi - dup1 __FUNC_SIG(decimals) eq decimalsJump jumpi - dup1 __FUNC_SIG(DOMAIN_SEPARATOR) eq domainSeparatorJump jumpi - - dup1 __FUNC_SIG(totalSupply) eq totalSupplyJump jumpi - dup1 __FUNC_SIG(balanceOf) eq balanceOfJump jumpi - dup1 __FUNC_SIG(allowance) eq allowanceJump jumpi - - dup1 __FUNC_SIG(transfer) eq transferJump jumpi - dup1 __FUNC_SIG(transferFrom) eq transferFromJump jumpi - dup1 __FUNC_SIG(approve) eq approveJump jumpi - - // Bubble up to the parent macro - no_match jump - - allowanceJump: - ALLOWANCE() - approveJump: - APPROVE() - balanceOfJump: - BALANCE_OF() - decimalsJump: - DECIMALS() - domainSeparatorJump: - DOMAIN_SEPARATOR() - nameJump: - NAME() - noncesJump: - NONCES() - permitJump: - PERMIT() - symbolJump: - SYMBOL() - totalSupplyJump: - TOTAL_SUPPLY() - transferFromJump: - TRANSFER_FROM() - transferJump: - TRANSFER() - - no_match: -} diff --git a/src/tokens/__TEMP__oqsfkvbhimsywiqwbdlilqoxezxnqvipERC721.huff b/src/tokens/__TEMP__oqsfkvbhimsywiqwbdlilqoxezxnqvipERC721.huff deleted file mode 100644 index 17f4c60b..00000000 --- a/src/tokens/__TEMP__oqsfkvbhimsywiqwbdlilqoxezxnqvipERC721.huff +++ /dev/null @@ -1,787 +0,0 @@ - -#define function mint(address, uint256) payable returns () -#define function burn(uint256) nonpayable returns () - -#define function mint(address, uint256) payable returns () -#define function burn(uint256) nonpayable returns () - -#define function safeMint(address to, uint256 tokenId, bytes memory data) payable returns () -#define function safeMint(address to, uint256 tokenId) payable returns () - -#define macro CONSTRUCTOR() = takes (0) returns (0) { - ERC721_CONSTRUCTOR() -} - -#define macro MINT() = takes (0) returns (0) { - 0x24 calldataload // [tokenId] - 0x04 calldataload // [to, tokenId] - _MINT() - stop -} - -#define macro BURN() = takes (0) returns (0) { - 0x04 calldataload // [tokenId] - _BURN() - stop -} - -#define macro SAFE_MINT() = takes (0) returns (0) { - 0x24 calldataload // [tokenId] - 0x04 calldataload // [to, tokenId] - _MINT() - - // Safe Logic - // Make sure we can transfer to the recipient - 0x04 calldataload // [to] - dup1 extcodesize // [to.code.length, to] - iszero safe jumpi // [to] - - // onERC721Received Selector - 0x150b7a02 dup1 // [onERC721Received, onERC721Received, to] - 0xE0 shl // [onERC721Received_shifted, onERC721Received, to] - - // Store the left-shifted selector for call - 0x20 mstore // [onERC721Received, to] - - // Store the msg.sender as the first arg - caller 0x24 mstore // [onERC721Received, to] - - // Store address(0) as the second arg - 0x00 // [address(0), onERC721Received, to] - 0x44 mstore // [onERC721Received, to] - - // Id is the third arg - 0x24 calldataload // [tokenId, onERC721Received, to] - 0x64 mstore // [onERC721Received, to] - - // Blank bytes array as 4th arg (no data) - 0x80 0x84 mstore - 0x00 0xA4 mstore - - // Call address(to).onERC721Received(msg.sender, from, tokenId, "") - 0x20 // [retSize, onERC721Received, to] - 0x00 // [retOffset, retSize, onERC721Received, to] - 0xA4 // [argSize, retOffset, retSize, onERC721Received, to] - dup3 // [argOffset, argSize, retOffset, retSize, onERC721Received, to] - dup3 // [value, argOffset, argSize, retOffset, retSize, onERC721Received, to] - dup7 // [to, value, argOffset, argSize, retOffset, retSize, onERC721Received, to] - gas // [gas, to, value, argOffset, argSize, retOffset, retSize, onERC721Received, to] - call // [success, onERC721Received, to] - - // Revert if call isn't successful - cont jumpi // [onERC721Received, to] - 0x00 dup1 revert - cont: - - // Compare the return data to the onERC721Received selector - 0x00 mload 0xE0 shr // [response, onERC721Received, to] - eq safe jumpi // [to] - - // Revert if the return data is not accepted - UNSAFE_RECIPIENT(0x00) - - // Stop execution if safe - safe: - stop -} - -#define macro SAFE_MINT_WITH_DATA() = takes (0) returns (0) { - 0x44 calldataload // [data] - 0x24 calldataload // [tokenId, data] - 0x04 calldataload // [to, tokenId, data] - _MINT() - - // Make sure we can transfer to the recipient - 0x04 calldataload // [to] - dup1 extcodesize // [to.code.length, to] - iszero safe jumpi // [to] - - // onERC721Received Selector - 0x150b7a02 dup1 // [onERC721Received, onERC721Received, to] - 0xE0 shl // [onERC721Received_shifted, onERC721Received, to] - - // Store the left-shifted selector for call - 0x20 mstore // [onERC721Received, to] - - // Store the msg.sender as the first arg - caller 0x24 mstore // [onERC721Received, to] - - // Store address(0) as the second arg - 0x00 // [address(0), onERC721Received, to] - 0x44 mstore // [onERC721Received, to] - - // Id is the third arg - 0x24 calldataload // [tokenId, onERC721Received, to] - 0x64 mstore // [onERC721Received, to] - - // Store the pointer to the data length - 0x80 0x84 mstore // [onERC721Received, to] - - 0x64 calldataload // [len(data), onERC721Received, to] - 0x05 shl // [len(data) * 0x20, onERC721Received, to] - 0x20 add // [len(data) * 0x20 + 0x20, onERC721Received, to] - dup1 // [len(data) * 0x20 + 0x20, len(data) * 0x20 + 0x20, onERC721received, to] - 0x64 // [0x64, len(data) * 0x20 + 0x20, len(data) * 0x20 + 0x20, onERC721received, to] - 0xA4 // [0x84, 0x64, len(data) * 0x20 + 0x20, len(data) * 0x20 + 0x20, onERC721received, to] - calldatacopy // [len(bytes), onERC721received, to] - - // Call address(to).onERC721Received(msg.sender, from, tokenId, bytes) - 0x20 // [retSize, len(bytes), onERC721Received, to] - 0x00 // [retOffset, retSize, len(bytes), onERC721Received, to] - swap1 swap2 // [len(bytes), retOffset, retSize, onERC721Received, to] - 0x84 add // [argSize, retOffset, retSize, onERC721Received, to] - dup3 // [argOffset, argSize, retOffset, retSize, len(bytes), onERC721Received, to] - dup3 // [value, argOffset, argSize, retOffset, retSize, len(bytes), onERC721Received, to] - dup7 // [to, value, argOffset, argSize, retOffset, retSize, len(bytes), onERC721Received, to] - gas // [gas, to, value, argOffset, argSize, retOffset, retSize, len(bytes), onERC721Received, to] - call // [success, len(bytes), onERC721Received, to] - - // Revert if call isn't successful - selector_call_success jumpi // [len(bytes), onERC721Received, to] - 0x00 dup1 revert - selector_call_success: - - // Compare the return data to the onERC721Received selector - 0x00 mload 0xE0 shr // [response, onERC721Received, to] - eq safe jumpi // [to] - - // Revert if the return data is not accepted - UNSAFE_RECIPIENT(0x00) - - // Stop execution if safe - safe: - stop - -} - -// Function Dispatch -#define macro MAIN() = takes (0) returns (0) { - 0x00 calldataload 0xE0 shr // [sig] - - // Mint and Burning Functions - dup1 __FUNC_SIG(mint) eq mint_jump jumpi - dup1 __FUNC_SIG(burn) eq burn_jump jumpi - - dup1 __FUNC_SIG("safeMint(address,uint256)") eq safe_mint jumpi - dup1 __FUNC_SIG("safeMint(address,uint256,bytes)") eq safe_mint_with_data jumpi - - dup1 __FUNC_SIG(approve) eq approve jumpi - dup1 __FUNC_SIG(setApprovalForAll) eq setApprovalForAll jumpi - - dup1 __FUNC_SIG(transferFrom) eq transferFrom jumpi - dup1 __FUNC_SIG(safeTransferFrom) eq safeTransferFrom jumpi - - dup1 __FUNC_SIG(name) eq name jumpi - dup1 __FUNC_SIG(symbol) eq symbol jumpi - dup1 __FUNC_SIG(tokenURI) eq tokenURI jumpi - dup1 __FUNC_SIG(supportsInterface) eq supportsInterface jumpi - - dup1 __FUNC_SIG(getApproved) eq getApproved jumpi - dup1 __FUNC_SIG(isApprovedForAll) eq isApprovedForAll jumpi - - dup1 __FUNC_SIG(balanceOf) eq balanceOf jumpi - dup1 __FUNC_SIG(ownerOf) eq ownerOf jumpi - - dup1 __FUNC_SIG("safeTransferFrom(address,address,uint256,bytes)") eq safeTransferFromData jumpi - - // Revert on failed dispatch - 0x00 dup1 revert - - safe_mint: - SAFE_MINT() - safe_mint_with_data: - SAFE_MINT_WITH_DATA() - - mint_jump: - MINT() - burn_jump: - BURN() - - approve: - APPROVE() - setApprovalForAll: - SET_APPROVAL_FOR_ALL() - - transferFrom: - TRANSFER_FROM() - safeTransferFrom: - SAFE_TRANSFER_FROM() - safeTransferFromData: - SAFE_TRANSFER_FROM_WITH_DATA() - - name: - NAME() - symbol: - SYMBOL() - tokenURI: - TOKEN_URI() - supportsInterface: - SUPPORTS_INTERFACE() - - getApproved: - GET_APPROVED() - isApprovedForAll: - IS_APPROVED_FOR_ALL() - - balanceOf: - BALANCE_OF() - ownerOf: - OWNER_OF() -} - - -/// @title ERC721 -/// @notice SPDX-License-Identifier: MIT -/// @author asnared -/// @author kadenzipfel -/// @notice Modern and heavily gas golfed ERC-721 implementation -/// @notice Adapted from Solmate https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC721.sol - -// Imports -#include "../utils/CommonErrors.huff" -#include "../auth/NonPayable.huff" -#include "../data-structures/Hashmap.huff" - -// Interface -#define function name() nonpayable returns (string) -#define function symbol() nonpayable returns (string) -#define function tokenURI(uint256) nonpayable returns (string) - -#define function mint(address, uint256) payable returns () -#define function burn(uint256) nonpayable returns () - -#define function transfer(address,uint256) nonpayable returns () -#define function transferFrom(address,address,uint256) nonpayable returns () -#define function safeTransferFrom(address,address,uint256) nonpayable returns () -#define function safeTransferFrom(address,address,uint256,bytes) nonpayable returns () - -#define function approve(address,uint256) nonpayable returns () -#define function setApprovalForAll(address,bool) nonpayable returns () - -#define function getApproved(uint256) view returns (address) -#define function isApprovedForAll(address,address) view returns (bool) -#define function ownerOf(uint256) view returns (address) -#define function balanceOf(address) view returns (uint256) -#define function supportsInterface(bytes4) view returns (bool) - -// Events -#define event Transfer(address,address,uint256) -#define event Approval(address,address,uint256) -#define event ApprovalForAll(address,address,bool) - -// Storage Slots -#define constant OWNER_LOCATION = FREE_STORAGE_POINTER() -#define constant BALANCE_LOCATION = FREE_STORAGE_POINTER() -#define constant SINGLE_APPROVAL_LOCATION = FREE_STORAGE_POINTER() - -// Immutables offsets -#define constant NAME_OFFSET = 0x0000000000000000000000000000000000000000000000000000000000000080 -#define constant NAME_LENGTH_OFFSET = 0x00000000000000000000000000000000000000000000000000000000000000a0 -#define constant SYMBOL_OFFSET = 0x0000000000000000000000000000000000000000000000000000000000000020 -#define constant SYMBOL_LENGTH_OFFSET = 0x0000000000000000000000000000000000000000000000000000000000000040 - -/// >>>>>>>>>>>>>>>>>>>>> CONSTRUCTOR <<<<<<<<<<<<<<<<<<<<<< /// - -/// @notice Constructor -#define macro ERC721_CONSTRUCTOR() = takes (0) returns (0) { - // Constructor arguments: - // ?, name_size, name, ?, symbol_size, symbol - - // This constructor will return the runtime bytecode with all the - // constructor arguments concatenated at the end. - - // Copy the runtime bytecode with constructor argument concatenated. - 0xb // [offset] - constructor code size - dup1 // [offset, offset] - codesize // [total_size, offset, offset] - sub // [runtime_size, offset] - dup1 // [runtime_size, runtime_size, offset] - swap2 // [offset, runtime_size, runtime_size] - returndatasize // [return_offset, offset, runtime_size, runtime_size] - codecopy // [runtime_size] - - // Return the runtime bytecode. - returndatasize // [return_offset, runtime_size] - return // [] -} - -/// >>>>>>>>>>>>>>>>>>>>> VIEW FUNCTIONS <<<<<<<<<<<<<<<<<<<<<< /// - -/// @notice Name -/// @notice Returns the token name string -#define macro NAME() = takes (0) returns (0) { - NON_PAYABLE() // [] - _GET_IMMUTABLE(NAME_OFFSET, 0x00) // [name_value] - _GET_IMMUTABLE(NAME_LENGTH_OFFSET, 0x00) // [name_length, name_value] - 0x20 0x00 mstore // [name_length, name_value] - 0x20 mstore // [name_value] - 0x40 mstore // [] - 0x60 0x00 return // [] -} - -/// @notice Symbol -/// @notice Returns the symbol of the token -#define macro SYMBOL() = takes (0) returns (0) { - NON_PAYABLE() // [] - _GET_IMMUTABLE(SYMBOL_OFFSET, 0x00) // [symbol_value] - _GET_IMMUTABLE(SYMBOL_LENGTH_OFFSET, 0x00) // [symbol_length, symbol_value] - 0x20 0x00 mstore // [symbol_length, symbol_value] - 0x20 mstore // [symbol_value] - 0x40 mstore // [] - 0x60 0x00 return // [] -} - -/// @notice Balance Of -/// @notice Returns the balance of the given address -#define macro BALANCE_OF() = takes (0) returns (0) { - NON_PAYABLE() // [] - 0x04 calldataload // [account] - [BALANCE_LOCATION] LOAD_ELEMENT_FROM_KEYS(0x00) // [balance] - 0x00 mstore // [] - 0x20 0x00 return // [] -} - -/// @notice Owner Of -/// @notice Returns the owner of the given token id -#define macro OWNER_OF() = takes (0) returns (0) { - 0x04 calldataload // [tokenId] - [OWNER_LOCATION] LOAD_ELEMENT_FROM_KEYS(0x00) // [owner] - 0x00 mstore // [] - 0x20 0x00 return // [] -} - -/// @notice Is Approved For All -/// @notice Returns whether the given operator is approved for all tokens of the given owner -#define macro IS_APPROVED_FOR_ALL() = takes (0) returns (0) { - 0x24 calldataload // [to] - 0x04 calldataload // [from, to] - LOAD_ELEMENT_FROM_KEYS(0x00) // [value] - 0x00 mstore // [] - 0x20 0x00 return // [] -} - -/// @notice Get Approved -/// @notice Returns the approved address for the given token id -#define macro GET_APPROVED() = takes (0) returns (0) { - 0x04 calldataload // [tokenId] - [SINGLE_APPROVAL_LOCATION] // [approval_slot, tokenId] - LOAD_ELEMENT_FROM_KEYS(0x00) // [spender] - 0x00 mstore // [] - 0x20 0x00 return // [] -} - -/// @notice Token URI -#define macro TOKEN_URI() = takes (0) returns (0) { - 0x20 0x00 mstore - 0x00 0x20 mstore - 0x40 0x00 return -} - -/// @notice Checks if the given interface is supported -#define macro SUPPORTS_INTERFACE() = takes (0) returns (0) { - // grab interfaceId - 0x04 calldataload // [interfaceId] - 0xe0 shr // [right_aligned_interfaceId] - - // Check if erc165 interfaceId - dup1 // [interfaceId, interfaceId] - 0x01ffc9a7 eq // [is_erc165, interfaceId] - is_interface jumpi - - // Check if erc721 interfaceId - dup1 // [interfaceId, interfaceId] - 0x80ac58cd eq // [is_erc721, interfaceId] - is_interface jumpi - - // Check if erc721Metadata interfaceId - 0x5b5e139f eq // [is_erc721Metadata] - is_interface jumpi - - // Return false (0x00) - 0x00 mstore // [] - 0x20 0x00 return // [] - - // Return true (0x01) - is_interface: - pop // [] - 0x01 0x00 mstore // [] - 0x20 0x00 return // [] -} - -/// >>>>>>>>>>>>>>>>>>>>> INTERNAL FUNCTIONS <<<<<<<<<<<<<<<<<<<<<< /// - -/// @notice Mint -/// @notice Mints a new token -/// @dev The Mint function is payable -#define macro _MINT() = takes (2) returns (0) { - // Input stack: // [to, tokenId] - // Output stack: // [] - - // Check that the recipient is valid - dup1 iszero invalid_recipient jumpi // [to, tokenId] - - // Create the minting params - 0x00 dup3 // [tokenId, from (0x00), to, tokenId] - - // Check token ownership - [OWNER_LOCATION] LOAD_ELEMENT_FROM_KEYS(0x00) // [owner, from (0x00), to, tokenId] - iszero iszero unauthorized jumpi - - // Give tokens to the recipient. - TRANSFER_GIVE_TO() // [from (0x00), to, tokenId] - - // Emit the transfer event. - __EVENT_HASH(Transfer) // [sig, from (0x00), to, tokenId] - 0x00 0x00 log4 // [] - - // Continue Executing - cont jump - - invalid_recipient: - INVALID_RECIPIENT(0x00) - - unauthorized: - ALREADY_MINTED(0x00) - - cont: -} - -/// @notice Burn -/// @notice Burns the token with the given id -#define macro _BURN() = takes (1) returns (0) { - // Input stack: // [tokenId] - NON_PAYABLE() // [tokenId] - - dup1 // [tokenId, tokenId] - [OWNER_LOCATION] LOAD_ELEMENT_FROM_KEYS(0x00) // [owner, tokenId] - - // Check that the recipient is valid - dup1 iszero // [owner == 0, owner, tokenId] - not_minted jumpi // [owner, tokenId] - - // Create the burning params - 0x00 swap1 // [owner, to (0x00), tokenId] - - // Reduce the balance of owner by 1 - 0x01 dup2 // [owner, 1, owner, to, tokenId] - [BALANCE_LOCATION] LOAD_ELEMENT_FROM_KEYS(0x00) // [balance, 1, owner, to, tokenId] - sub dup2 // [owner, balance-1, owner, to, tokenId] - [BALANCE_LOCATION] - STORE_ELEMENT_FROM_KEYS(0x00) // [owner, to, tokenId] - - // Set the owner of the token to 0x00 - 0x00 dup4 [OWNER_LOCATION] // [slot, owner, 0x00, owner, to, tokenId] - STORE_ELEMENT_FROM_KEYS(0x00) // [owner, to, tokenId] - - // Set the approval of the token to 0x00 for the owner - 0x00 dup4 [SINGLE_APPROVAL_LOCATION] // [slot, owner, 0x00, owner, to, tokenId] - STORE_ELEMENT_FROM_KEYS(0x00) // [owner, to, tokenId] - - // Emit the transfer event. - __EVENT_HASH(Transfer) // [sig, owner, to (0x00), tokenId] - 0x00 0x00 // [0, 0, sig, owner, to (0x00), tokenId] - log4 // [] - - // Continue Executing - cont jump - - not_minted: - NOT_MINTED(0x00) - - cont: -} - -/// @notice Retrives an "immutable" from the runtime bytecode. -#define macro _GET_IMMUTABLE(offset_end, free_memory) = takes (0) returns (1) { - 0x20 // [size] - codesize sub // [offset_code, size] - // [offset_memory, offset_code, size] - codecopy // [] - mload // [value] -} - -/// >>>>>>>>>>>>>>>>>>>>> EXTERNAL FUNCTIONS <<<<<<<<<<<<<<<<<<<<<< /// - -/// @notice Approve -/// @notice Approves a spender for a specific token -#define macro APPROVE() = takes (0) returns (0) { - // Load the token owner - 0x24 calldataload dup1 // [tokenId, tokenId] - [OWNER_LOCATION] - LOAD_ELEMENT_FROM_KEYS(0x00) // [owner, tokenId] - dup1 caller eq // [is_sender_owner, owner, tokenId] - - // Check if approved for all - caller dup3 // [owner, msg.sender, is_sender_owner, owner, tokenId] - LOAD_ELEMENT_FROM_KEYS(0x00) // [is_approved_for_all, is_sender_owner, owner, tokenId]] - or cont jumpi // [owner, tokenId] - not_authorized jump - cont: - - // Store approval - 0x04 calldataload dup1 dup4 // [tokenId, spender, spender, owner, tokenId] - [SINGLE_APPROVAL_LOCATION] - STORE_ELEMENT_FROM_KEYS(0x00) // [spender, owner, tokenId] - swap1 // [owner, spender, tokenId] - - // Emit the approval event - __EVENT_HASH(Approval) // [sig, owner, spender, tokenId] - 0x00 0x00 log4 // [] - - stop - - not_authorized: - UNAUTHORIZED(0x00) -} - -/// @notice Set Approval For All -/// @notice Sets an operator as approved for all tokens of the caller -#define macro SET_APPROVAL_FOR_ALL() = takes (0) returns (0) { - // Store the operator as approved for all - 0x24 calldataload // [approved] - 0x04 calldataload // [operator, approved] - caller // [msg.sender, operator, approved] - STORE_ELEMENT_FROM_KEYS(0x00) // [] - - // Emit the ApprovalForAll event - 0x24 calldataload // [approved] - 0x04 calldataload // [operator, approved] - caller // [msg.sender, operator, approved] - __EVENT_HASH(ApprovalForAll) // [sig, owner, operator] - 0x00 0x00 // [0, 32, sig, owner, operator] - log4 // [] - - // Stop execution - stop -} - -/// @notice Transfer From -/// @notice Transfers a token from one address to another -#define macro TRANSFER_FROM() = takes (0) returns (0) { - // Setup the stack for the transfer function. - 0x44 calldataload // [tokenId] - 0x24 calldataload // [to, tokenId] - 0x04 calldataload // [from, to, tokenId] - - // Accounting Logic - TRANSFER_TAKE_FROM() // [from, to, tokenId] - TRANSFER_GIVE_TO() // [from, to, tokenId] - - // Emit the transfer event - __EVENT_HASH(Transfer) // [sig,from, to, tokenId] - 0x20 0x00 log4 // [] - - // Stop execution - stop -} - -/// @notice Safe Transfer From -#define macro SAFE_TRANSFER_FROM() = takes (0) returns (0) { - // Setup the stack for the transfer function. - 0x44 calldataload // [tokenId] - 0x24 calldataload // [to, tokenId] - 0x04 calldataload // [from, to, tokenId] - - TRANSFER_TAKE_FROM() // [from, to, tokenId] - TRANSFER_GIVE_TO() // [from, to, tokenId] - - // Emit the transfer event - __EVENT_HASH(Transfer) // [sig, from, to, tokenId] - 0x00 0x00 log4 // [] - - // Make sure we can transfer to the recipient - 0x24 calldataload // [to] - dup1 extcodesize // [to.code.length, to] - iszero safe jumpi // [to] - - // onERC721Received Selector - 0x150b7a02 dup1 // [onERC721Received, onERC721Received, to] - 0xE0 shl // [onERC721Received_shifted, onERC721Received, to] - - // Store the left-shifted selector for call - 0x20 mstore // [onERC721Received, to] - - // Store the msg.sender as the first arg - caller 0x24 mstore // [onERC721Received, to] - - // Store from as the second arg - 0x04 calldataload // [from, onERC721Received, to] - 0x44 mstore // [onERC721Received, to] - - // Id is the third arg - 0x44 calldataload // [tokenId, onERC721Received, to] - 0x64 mstore // [onERC721Received, to] - - // Blank bytes array as 4th arg (no data) - 0x80 0x84 mstore - 0x00 0xA4 mstore - - // Call address(to).onERC721Received(msg.sender, from, tokenId, "") - 0x20 // [retSize, onERC721Received, to] - 0x00 // [retOffset, retSize, onERC721Received, to] - 0xA4 // [argSize, retOffset, retSize, onERC721Received, to] - dup3 // [argOffset, argSize, retOffset, retSize, onERC721Received, to] - dup3 // [value, argOffset, argSize, retOffset, retSize, onERC721Received, to] - dup7 // [to, value, argOffset, argSize, retOffset, retSize, onERC721Received, to] - gas // [gas, to, value, argOffset, argSize, retOffset, retSize, onERC721Received, to] - call // [success, onERC721Received, to] - - // Revert if call isn't successful - cont jumpi // [onERC721Received, to] - 0x00 dup1 revert - cont: - - // Compare the return data to the onERC721Received selector - 0x00 mload 0xE0 shr // [response, onERC721Received, to] - eq safe jumpi // [to] - - // Revert if the return data is not accepted - UNSAFE_RECIPIENT(0x00) - - // Stop execution if safe - safe: - stop -} - -#define macro SAFE_TRANSFER_FROM_WITH_DATA() = takes (0) returns (0) { - // Setup the stack for the transfer function. - 0x44 calldataload // [tokenId] - 0x24 calldataload // [to, tokenId] - 0x04 calldataload // [from, to, tokenId] - - TRANSFER_TAKE_FROM() // [from, to, tokenId] - TRANSFER_GIVE_TO() // [from, to, tokenId] - - // Emit the transfer event. - __EVENT_HASH(Transfer) // [sig, from, to, tokenId] - 0x00 0x00 log4 // [] - - // Make sure we can transfer to the recipient - 0x24 calldataload // [to] - dup1 extcodesize // [to.code.length, to] - iszero safe jumpi // [to] - - // onERC721Received Selector - 0x150b7a02 dup1 // [onERC721Received, onERC721Received, to] - 0xE0 shl // [onERC721Received_shifted, onERC721Received, to] - - // Store the left-shifted selector for call - 0x20 mstore // [onERC721Received, to] - - // Store the msg.sender as the first arg - caller 0x24 mstore // [onERC721Received, to] - - // Store from as the second arg - 0x04 calldataload // [from, onERC721Received, to] - 0x44 mstore // [onERC721Received, to] - - // Id is the third arg - 0x44 calldataload // [tokenId, onERC721Received, to] - 0x64 mstore // [onERC721Received, to] - - 0x84 calldataload // [len(data), onERC721Received, to] - 0x05 shl // [len(data) * 0x20, onERC721Received, to] - 0x40 add // [len(data) * 0x20 + 0x40, onERC721Received, to] - dup1 // [len(data) * 0x20 + 0x40, len(data) * 0x20 + 0x40, onERC721received, to] - 0x64 // [0x64, len(data) * 0x20 + 0x40, len(data) * 0x20 + 0x40, onERC721received, to] - 0x84 // [0x20, 0x64, len(data) * 0x20 + 0x40, len(data) * 0x20 + 0x40, onERC721received, to] - calldatacopy // [len(bytes), onERC721received, to] - - // Call address(to).onERC721Received(msg.sender, from, tokenId, bytes) - 0x20 // [retSize, len(bytes), onERC721Received, to] - 0x00 // [retOffset, retSize, len(bytes), onERC721Received, to] - swap1 swap2 // [len(bytes), retOffset, retSize, onERC721Received, to] - 0x64 add // [argSize, retOffset, retSize, onERC721Received, to] - dup3 // [argOffset, argSize, retOffset, retSize, len(bytes), onERC721Received, to] - dup3 // [value, argOffset, argSize, retOffset, retSize, len(bytes), onERC721Received, to] - dup7 // [to, value, argOffset, argSize, retOffset, retSize, len(bytes), onERC721Received, to] - gas // [gas, to, value, argOffset, argSize, retOffset, retSize, len(bytes), onERC721Received, to] - call // [success, len(bytes), onERC721Received, to] - - // Revert if call isn't successful - cont jumpi // [len(bytes), onERC721Received, to] - 0x00 dup1 revert - cont: - - // Compare the return data to the onERC721Received selector - 0x00 mload 0xE0 shr // [response, onERC721Received, to] - eq safe jumpi // [to] - - // Revert if the return data is not accepted - UNSAFE_RECIPIENT(0x00) - - // Stop execution if safe - safe: - stop -} - -/// >>>>>>>>>>>>>>>>>>>>> INTERNAL HELPERS <<<<<<<<<<<<<<<<<<<<<< /// - -/// @notice Internal Macro to update Transfer from accounting -#define macro TRANSFER_TAKE_FROM() = takes (3) returns (3) { - // Input stack: [from, to, tokenId] - - // If from !== ownerOf[tokenId] revert with "WRONG_FROM" - dup1 dup4 // [tokenId, from, from, to, tokenId] - [OWNER_LOCATION] LOAD_ELEMENT_FROM_KEYS(0x00) // [owner, from, from, to, tokenId] - eq cont jumpi // [from, to, tokenId] - WRONG_FROM(0x00) - cont: - - // If to === address(0) revert with "INVALID_RECIPIENT" - dup2 iszero iszero continue jumpi // [from, to, tokenId] - INVALID_RECIPIENT(0x00) - continue: - - // Check if msg.sender == from - dup1 caller eq // [msg.sender == from, from, to, tokenId] - is_authorized jumpi // [from, to, tokenId] - - // Check if approved for all - caller dup2 // [from, msg.sender, from, to, tokenId] - LOAD_ELEMENT_FROM_KEYS(0x00) // [is_approved_for_all, from, to, tokenId] - is_authorized jumpi // [from, to, tokenId] - - // Check if approved for tokenId - dup3 // [tokenId, from, to, tokenId] - [SINGLE_APPROVAL_LOCATION] // [SINGLE_APPROVAL_LOCATION, tokenId, from, to, tokenId] - LOAD_ELEMENT_FROM_KEYS(0x00) // [address_approved_for_tokenId, from, to, tokenId] - caller eq is_authorized jumpi // [from, to, tokenId] - - // If msg.sender != from && !isApprovedForAll[from][msg.sender] && msg.sender != getApproved[id], - UNAUTHORIZED(0x00) - - is_authorized: - - // Update balance of from - 0x01 dup2 // [from, 1, from, to, tokenId] - [BALANCE_LOCATION] LOAD_ELEMENT_FROM_KEYS(0x00) // [balance, 1, from, to, tokenId] - sub dup2 // [from, balance-1, from, to, tokenId] - [BALANCE_LOCATION] - STORE_ELEMENT_FROM_KEYS(0x00) // [from, to, tokenId] -} - -/// @notice Internal Macro to update Transfer to accounting -#define macro TRANSFER_GIVE_TO() = takes (3) returns (3) { - // retrieve balance - // input stack: // [from, to, tokenId] - dup2 // [to, from, to, tokenId] - [BALANCE_LOCATION] // [balance_slot, to, from, to, tokenId] - LOAD_ELEMENT_FROM_KEYS(0x00) // [balance, from, to, tokenId] - 0x01 add // [balance+1, from, to, tokenId] - - // update balance - dup3 // [to, balance+1, from, to, tokenId] - [BALANCE_LOCATION] // [balance_slot, to, balance+1, from, to, tokenId] - STORE_ELEMENT_FROM_KEYS(0x00) // [from, to, tokenId] - - // update ownerOf - dup2 dup4 // [tokenId, to, from, to, tokenId] - [OWNER_LOCATION] // [owner_slot, tokenId, to, from, to, tokenId] - STORE_ELEMENT_FROM_KEYS(0x00) // [from, to, tokenId] - - // update approval - 0x00 dup4 // [tokenId, address(0), from, to, tokenId] - [SINGLE_APPROVAL_LOCATION] // [approval_slot, tokenId, address(0), from, to, tokenId] - STORE_ELEMENT_FROM_KEYS(0x00) // [from, to, tokenId] -} diff --git a/src/tokens/__TEMP__tdpvmgiyjorautmnplhzvgjsaeubpvhbERC4626.huff b/src/tokens/__TEMP__tdpvmgiyjorautmnplhzvgjsaeubpvhbERC4626.huff deleted file mode 100644 index 5e3a3cbb..00000000 --- a/src/tokens/__TEMP__tdpvmgiyjorautmnplhzvgjsaeubpvhbERC4626.huff +++ /dev/null @@ -1,859 +0,0 @@ - -#define function beforeWithdrawHookCalledCounter() nonpayable returns (uint256) -#define function afterDepositHookCalledCounter() nonpayable returns (uint256) - -#define constant BEFORE_HOOK_COUNTER = FREE_STORAGE_POINTER() -#define constant AFTER_HOOK_COUNTER = FREE_STORAGE_POINTER() - -#define macro CONSTRUCTOR() = takes (0) returns (0) { - ERC4626_CONSTRUCTOR() // [] -} - -#define macro BEFORE_WITHDRAW() = takes (2) returns (0) { - // Input Stack: [assets, shares] - // Output Stack: [] - pop pop // [] - [BEFORE_HOOK_COUNTER] sload // [counter] - 0x01 add // [counter + 1] - [BEFORE_HOOK_COUNTER] sstore // [] -} - -#define macro AFTER_DEPOSIT() = takes (2) returns (0) { - // Input Stack: [assets, shares] - // Output Stack: [] - pop pop // [] - [AFTER_HOOK_COUNTER] sload // [counter] - 0x01 add // [counter + 1] - [AFTER_HOOK_COUNTER] sstore // [] -} - -#define macro READ_BEFORE_HOOK_COUNTER() = takes (0) returns (0) { - [BEFORE_HOOK_COUNTER] sload // [counter] - 0x00 mstore // [] - 0x20 0x00 return // [] -} - -#define macro READ_AFTER_HOOK_COUNTER() = takes (0) returns (0) { - [AFTER_HOOK_COUNTER] sload // [counter] - 0x00 mstore // [] - 0x20 0x00 return // [] -} - -#define macro TOTAL_ASSETS_INNER() = takes (0) returns (1) { - // Input Stack: [] - // Output Stack: [total_assets] - - // Store the asset.balanceOf(address(this)) args in memory - __FUNC_SIG(balanceOf) - 0xE0 shl - 0x20 mstore - address 0x24 mstore - - // Get the asset variable - _GET_IMMUTABLE(ASSET_OFFSET, 0x80) // [asset] - - // Construct the call - 0x20 // [retSize, asset] - 0x00 // [retOffset, retSize, asset] - 0x24 // [argSize, retOffset, retSize, asset] - 0x20 // [argOffset, argSize, retOffset, retSize, asset] - 0x00 // [value, argOffset, argSize, retOffset, retSize, asset] - dup6 // [to, value, argOffset, argSize, retOffset, retSize, asset] - gas // [gas, to, value, argOffset, argSize, retOffset, retSize, asset] - call // [success, asset] - - // Verify the call succeeded - iszero iszero success jumpi // [asset] - 0x00 dup1 revert // [] - success: - - // Since the returndata is copied to [0x00:0x20], we can just mload - pop 0x00 mload // [total_assets] -} - - -#define macro MAIN() = takes (0) returns (0) { - pc calldataload 0xE0 shr // [sig] - - dup1 __FUNC_SIG(beforeWithdrawHookCalledCounter) eq before_jump jumpi // [sig] - dup1 __FUNC_SIG(afterDepositHookCalledCounter) eq after_jump jumpi // [sig] - - ERC4626_MAIN() // [sig] - - 0x00 dup1 revert - - before_jump: - READ_BEFORE_HOOK_COUNTER() - after_jump: - READ_AFTER_HOOK_COUNTER() -} - - -/// @title ERC4626 -/// @notice SPDX-License-Identifier: MIT -/// @author asnared -/// @notice Minimal ERC4626 tokenized Vault implementation. -/// @notice Adapted from Solmate (https://github.com/transmissions11/solmate/blob/main/src/mixins/ERC4626.sol) - -// ERC4626 is ERC20 -#include "./ERC20.huff" -#include "../utils/CommonErrors.huff" -#include "../math/FixedPointMath.huff" - -// Events -#define event Deposit(address indexed caller, address indexed owner, uint256 assets, uint256 shares) -#define event Withdraw(address indexed caller, address indexed receiver, address indexed owner, uint256 assets, uint256 shares) - -// Interface -#define function asset() view returns (address) - -#define function deposit(uint256 assets, address receiver) payable returns (uint256 shares) -#define function withdraw(uint256 assets, address receiver, address owner) payable returns (uint256 shares) -#define function mint(uint256 shares, address receiver) payable returns (uint256 assets) -#define function redeem(uint256 shares, address receiver, address owner) payable returns (uint256 assets) - -#define function totalAssets() view returns (uint256) -#define function convertToShares(uint256 assets) view returns (uint256) -#define function convertToAssets(uint256 shares) view returns (uint256) -#define function previewDeposit(uint256 assets) view returns (uint256) -#define function previewMint(uint256 shares) view returns (uint256) -#define function previewWithdraw(uint256 assets) view returns (uint256) -#define function previewRedeem(uint256 shares) view returns (uint256) - -#define function maxDeposit(address) view returns (uint256) -#define function maxMint(address) view returns (uint256) -#define function maxWithdraw(address owner) view returns (uint256) -#define function maxRedeem(address owner) view returns (uint256) - -// Immutables offsets -#define constant ASSET_OFFSET = 0x0000000000000000000000000000000000000000000000000000000000000100 - -#define constant TYPE_UINT_256_MAX = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff - -/// @notice Constructor -#define macro ERC4626_CONSTRUCTOR() = takes (0) returns (0) { - // Copy the asset address into memory and then the stack from the bytecode - 0x20 // [size] - byte size to copy - 0x20 [ASSET_OFFSET] sub // [asset_offset_now, size] - codesize sub // [offset, size] - offset in the code to copy from - 0x00 // [mem, offset, size] - offset in memory to copy to - codecopy // [] - stores asset at 0x00 - - // Store the decimals function selector in memory to call - __FUNC_SIG(decimals) // [sig_right_padded] - 0xE0 shl // [sig_left_padded] - 0x20 mstore // [] - - // Call the asset to get its decimals - 0x20 // [retSize] - 0x00 // [retOffset, retSize] - 0x04 // [argSize, retOffset, retSize] - 0x20 // [argOffset, argSize, retOffset, retSize] - 0x00 mload // [to, argOffset, argSize, retOffset, retSize] - gas // [gas, to, argOffset, argSize, retOffset, retSize] - staticcall // [success] - - // If the call failed, revert - cont jumpi // [] - 0x00 dup1 revert // [] - cont: - - // Load the decimals - 0x00 mload // [decimals] - - // Configure the initial domain separator - chainid [INITIAL_CHAIN_ID] sstore // [decimals] - COMPUTE_DOMAIN_SEPARATOR() // [DOMAIN_SEPARATOR, decimals] - [INITIAL_DOMAIN_SEPARATOR] sstore // [decimals] - - // Copy the runtime bytecode with constructor argument concatenated. - __codesize(CONSTRUCTOR) // [offset, decimals] - dup1 // [offset, offset, decimals] - codesize // [total_size, offset, offset, decimals] - sub // [runtime_size, offset, decimals] - dup1 // [runtime_size, runtime_size, offset, decimals] - swap2 // [offset, runtime_size, runtime_size, decimals] - returndatasize // [return_offset, offset, runtime_size, runtime_size, decimals] - codecopy // [runtime_size, decimals] - - // Add the decimals at the of the bytecode. - swap1 // [decimals, runtime_size] - dup2 // [runtime_size, decimals, runtime_size] - returndatasize add mstore // [runtime_size] - - // Return the runtime bytecode. - 0x20 add // [new_runtime_size] - returndatasize // [return_offset, new_runtime_size] - return // [] -} - -/// @notice Returns the ERC4626 decimals -#define macro ERC4626_DECIMALS() = takes (0) returns (0) { - _GET_IMMUTABLE(DECIMALS_OFFSET, 0x00) // [decimals] - 0x00 mstore // [] - 0x20 0x00 return // [] -} - -/// @notice Returns the ERC4626 asset -#define macro ERC4626_ASSET() = takes (0) returns (0) { - _GET_IMMUTABLE(ASSET_OFFSET, 0x00) // [asset] - 0x00 mstore // [] - 0x20 0x00 return // [] -} - -// ------------------------------------------------------ -// DEPOSIT/WITHDRAWAL LOGIC -// ------------------------------------------------------ - -/// @notice Mint -/// @notice Mints a {receiver} x amount of {assets} proportional to the input {shares} -/// @param {shares} [uint256] The amount of shares to mint -#define macro ERC4626_MINT() = takes (0) returns (0) { - 0x24 calldataload // [receiver] - 0x04 calldataload // [shares, receiver] - MINT_INNER() // [assets] - 0x00 mstore // [] - 0x20 0x00 return // [] -} - -/// @notice Mint Internal Helper -#define macro MINT_INNER() = takes (2) returns (1) { - // Input stack: [shares, receiver] - // Output stack: [assets] - - // Preview the mint given the number of shares - dup1 // [shares, shares, receiver] - PREVIEW_MINT_INNER() // [assets, shares, receiver] - - // Transfer the assets from the caller to the vault - - // Store the transferFrom selector in memory - __FUNC_SIG(transferFrom) // [selector, assets, shares, receiver] - 0xE0 shl // [selector, assets, shares, receiver] - 0x00 mstore // [assets, shares, receiver] - - // Store the caller in memory as the first arg - caller 0x04 mstore // [assets, shares, receiver] - - // Store this address as the second call argument in memory - address 0x24 mstore // [assets, shares, receiver] - - // Store assets as the third call argument in memory - dup1 0x44 mstore // [assets, shares, receiver] - - // Load the asset as the call destination - _GET_IMMUTABLE(ASSET_OFFSET, 0x80) // [asset, assets, shares, receiver] - - // Construct the call - 0x00 // [retSize, asset, assets, shares, receiver] - 0x00 // [retOffset, retSize, asset, assets, shares, receiver] - 0x64 // [argSize, retOffset, retSize, asset, assets, shares, receiver] - 0x00 // [argOffset, argSize, retOffset, retSize, asset, assets, shares, receiver] - 0x00 // [value, argOffset, argSize, retOffset, retSize, asset, assets, shares, receiver] - dup6 // [to, value, argOffset, argSize, retOffset, retSize, asset, assets, shares, receiver] - gas // [gas, to, value, argOffset, argSize, retOffset, retSize, asset, assets, shares, receiver] - call // [success, asset, assets, shares, receiver] - - // Verify the call succeeded - success jumpi // [asset, assets, shares, receiver] - 0x00 dup1 revert // [] - success: - - // Mint vault shares to the receiver - pop // [assets, shares, receiver] - dup3 dup3 // [shares, receiver, assets, shares, receiver] - _MINT() // [assets, shares, receiver] - - // Emit the deposit event - dup1 0x00 mstore // [assets, shares, receiver] - dup2 0x20 mstore // [assets, shares, receiver] - dup3 caller // [msg.sender, receiver, assets, shares, receiver] - __EVENT_HASH(Deposit) // [event_hash, msg.sender, receiver, assets, shares, receiver] - 0x40 0x00 log3 // [assets, shares, receiver] - - // Call the after deposit hook - swap1 dup2 // [assets, shares, assets, receiver] - AFTER_DEPOSIT() // [assets, receiver] - - // Return just the assets - swap1 pop // [assets] -} - -/// @notice Redeem -/// @notice Redeems a {receiver} x amount of {assets} proportional to the input {shares} -/// @param {shares} [uint256] The amount of shares to redeem -/// @param {receiver} [address] The address to receive the assets -/// @param {owner} [address] The address that owns the shares -#define macro ERC4626_REDEEM() = takes (0) returns (0) { - 0x44 calldataload // [owner] - 0x24 calldataload // [receiver, owner] - 0x04 calldataload // [shares, receiver, owner] - REDEEM_INNER() // [assets] - 0x00 mstore // [] - 0x20 0x00 return // [] -} - -/// @notice Redeem Internal Helper -#define macro REDEEM_INNER() = takes (3) returns (1) { - // Input stack: [shares, receiver, owner] - // Output stack: [assets] - - // Jump ahead if msg.sender == owner - dup3 caller eq ahead jumpi // [shares, receiver, owner] - - // Check if the caller is approved to redeem the shares - - // Get the allowance[owner][msg.sender] - caller dup4 // [owner, msg.sender, shares, receiver, owner] - [APPROVAL_SLOT] // [slot, owner, msg.sender, shares, receiver, owner] - LOAD_ELEMENT_FROM_KEYS_2D(0x00) // [allowance, shares, receiver, owner] - - // If the allowed is no infinite approval, set to the allowance less shares - dup1 [TYPE_UINT_256_MAX] // [type(uint256).max, allowance, allowance, shares, receiver, owner] - eq infinite jumpi // [allowance, shares, receiver, owner] - - // Set the new allowance - dup2 dup2 sub // [new_allowance, allowance, shares, receiver, owner] - caller dup6 [APPROVAL_SLOT] // [slot, owner, msg.sender, new_allowance, allowance, shares, receiver, owner] - STORE_ELEMENT_FROM_KEYS_2D(0x00) // [allowance, shares, receiver, owner] - - // Jump dests for initial checks - infinite: - pop // [shares, receiver, owner] - ahead: - - // Validate that the assets are non-zero - dup1 CONVERT_TO_ASSETS_INNER() // [assets, shares, receiver, owner] - dup1 non_zero jumpi // [assets, shares, receiver, owner] - ZERO_ASSETS(0x00) - non_zero: - - // Call the before withdraw hook - dup2 dup2 BEFORE_WITHDRAW() // [assets, shares, receiver, owner] - - // Burn the shares, input stack: [shares, owner] - dup4 dup3 _BURN() // [assets, shares, receiver, owner] - - // Emit the withdraw event - dup1 0x00 mstore // [assets, shares, receiver, owner] - dup2 0x20 mstore // [assets, shares, receiver, owner] - dup4 dup4 caller // [msg.sender, receiver, owner, assets, shares, receiver, owner] - __EVENT_HASH(Withdraw) // [event_hash, msg.sender, receiver, owner, assets, shares, receiver, owner] - 0x40 0x00 log4 // [assets, shares, receiver, owner] - - // Transfer the assets from the receiver to the vault - // Store the transfer selector in memory - __FUNC_SIG(transfer) // [selector, assets, shares, receiver, owner] - 0xE0 shl // [selector, assets, shares, receiver, owner] - 0x00 mstore // [assets, shares, receiver, owner] - - // Store the receiver in memory as the first arg - dup3 0x04 mstore // [assets, shares, receiver, owner] - - // Store the assets as the second call argument in memory - dup1 0x24 mstore // [assets, shares, receiver, owner] - - // Load the asset as the call destination - _GET_IMMUTABLE(ASSET_OFFSET, 0x80) // [asset, assets, shares, receiver, owner] - // [ADDRESS] - - // Construct the call - 0x00 // [retSize, asset, assets, shares, receiver, owner] - 0x00 // [retOffset, retSize, asset, assets, shares, receiver, owner] - 0x44 // [argSize, retOffset, retSize, asset, assets, shares, receiver, owner] - 0x00 // [argOffset, argSize, retOffset, retSize, asset, assets, shares, receiver, owner] - 0x00 // [value, argOffset, argSize, retOffset, retSize, asset, assets, shares, receiver, owner] - dup6 // [to, value, argOffset, argSize, retOffset, retSize, asset, assets, shares, receiver, owner] - gas // [gas, to, value, argOffset, argSize, retOffset, retSize, asset, assets, shares, receiver, owner] - call // [success, asset, assets, shares, receiver, owner] - - // Verify the call succeeded - success jumpi // [asset, assets, shares, receiver, owner] - 0x00 dup1 revert // [] - success: - - // Clean the stack and return the assets - pop swap4 pop pop pop // [assets] -} - -/// @notice Deposit -/// @notice Deposits the asset in exchange for shares -/// @param {assets} [uint256] The amount of assets to deposit -/// @param {receiver} [address] The address to receive the shares -#define macro ERC4626_DEPOSIT() = takes (0) returns (0) { - 0x24 calldataload // [receiver] - 0x04 calldataload // [assets, receiver] - DEPOSIT_INNER() // [shares] - 0x00 mstore // [] - 0x20 0x00 return // [] -} - -/// @notice Deposit assets into the ERC4626 Vault -#define macro DEPOSIT_INNER() = takes (2) returns (1) { - // Input stack: [assets, receiver] - // Output stack: [shares] - - // Validate that the assets shares are not zero - dup1 // [assets, assets, receiver] - PREVIEW_DEPOSIT_INNER() // [shares, assets, receiver] - dup1 cont jumpi // [shares, assets, receiver] - ZERO_SHARES(0x00) - cont: - - // Store the transferFrom selector in memory - __FUNC_SIG(transferFrom) // [selector, shares, assets, receiver] - 0xE0 shl // [selector, shares, assets, receiver] - 0x00 mstore // [shares, assets, receiver] - - // Store the caller in memory as the first arg - caller 0x04 mstore // [shares, assets, receiver] - - // Store this address as the second call argument in memory - address 0x24 mstore // [shares, assets, receiver] - - // Store assets as the third call argument in memory - dup2 0x44 mstore // [shares, assets, receiver] - - // Load the asset - _GET_IMMUTABLE(ASSET_OFFSET, 0x80) // [asset, shares, assets, receiver] - - // Construct the call - 0x00 // [retSize, asset, shares, assets, receiver] - 0x00 // [retOffset, retSize, asset, shares, assets, receiver] - 0x64 // [argSize, retOffset, retSize, asset, shares, assets, receiver] - 0x00 // [argOffset, argSize, retOffset, retSize, asset, shares, assets, receiver] - 0x00 // [value, argOffset, argSize, retOffset, retSize, asset, shares, assets, receiver] - dup6 // [to, value, argOffset, argSize, retOffset, retSize, asset, shares, assets, receiver] - gas // [gas, to, value, argOffset, argSize, retOffset, retSize, asset, shares, assets, receiver] - call // [success, asset, shares, assets, receiver] - - // Verify the call succeeded - success jumpi // [asset, shares, assets, receiver] - 0x00 dup1 revert // [] - success: - - // Mint to the receiver - pop dup3 dup2 // [shares, receiver, shares, assets, receiver] - - _MINT() // [shares, assets, receiver] - - // Emit the Deposit Event - dup2 0x00 mstore // [shares, assets, receiver] - dup1 0x20 mstore // [shares, assets, receiver] - dup3 caller // [msg.sender, receiver, shares, assets, receiver] - __EVENT_HASH(Deposit) // [event_hash, msg.sender, receiver, shares, assets, receiver] - 0x40 0x00 log3 // [shares, assets, receiver] - - // Call the after deposit hook - dup1 swap2 swap1 // [shares, assets, shares, receiver] - AFTER_DEPOSIT() // [shares, receiver] - - // Return the shares - swap1 pop // [shares] -} - -/// @notice Withdraw -/// @notice Withdraws the shares in exchange for the underlying assets -/// @param {assets} [uint256] The amount of shares to withdraw -/// @param {receiver} [address] The address to receive the assets -/// @param {owner} [address] The address that owns the shares -#define macro ERC4626_WITHDRAW() = takes (0) returns (0) { - 0x44 calldataload // [owner] - 0x24 calldataload // [receiver, owner] - 0x04 calldataload // [assets, receiver, owner] - WITHDRAWAL_INNER() // [shares] - 0x00 mstore // [] - 0x20 0x00 return // [] -} - -/// @notice Withdraws assets from an ERC4626 Vault -#define macro WITHDRAWAL_INNER() = takes (3) returns (1) { - // Input stack: [assets, receiver, owner] - // Output stack: [shares] - - // Get the shares from the assets - dup1 PREVIEW_WITHDRAW_INNER() // [shares, assets, receiver, owner] - - // Skip ahead if msg.sender is the owner - dup4 caller eq owner_jump jumpi // [shares, assets, receiver, owner] - - // Get the allowance[owner][msg.sender] - caller dup5 // [owner, msg.sender, shares, assets, receiver, owner] - [APPROVAL_SLOT] // [slot, owner, msg.sender, shares, assets, receiver, owner] - LOAD_ELEMENT_FROM_KEYS_2D(0x00) // [allowance, shares, assets, receiver, owner] - - // If the allowed is no infinite approval, set to the allowance less shares - dup1 [TYPE_UINT_256_MAX] // [type(uint256).max, allowance, allowance, shares, assets, receiver, owner] - eq infinite jumpi // [allowance, shares, assets, receiver, owner] - - // Set the new allowance - dup2 dup2 sub // [new_allowance, allowance, shares, assets, receiver, owner] - caller dup6 [APPROVAL_SLOT] // [slot, owner, msg.sender, new_allowance, allowance, shares, assets, receiver, owner] - STORE_ELEMENT_FROM_KEYS_2D(0x00) // [allowance, shares, assets, receiver, owner] - - infinite: - pop // [shares, assets, receiver, owner] - - owner_jump: - - // Call the before withdrawal hook - dup1 dup3 // [assets, shares, shares, assets, receiver, owner] - BEFORE_WITHDRAW() // [shares, assets, receiver, owner] - - // Burn the shares - dup4 dup2 // [shares, owner, shares, assets, receiver, owner] - _BURN() // [shares, assets, receiver, owner] - - // Emit the Withdraw Event - dup2 0x00 mstore // [shares, assets, receiver, owner] - dup1 0x20 mstore // [shares, assets, receiver, owner] - dup4 dup3 caller // [msg.sender, assets, owner, shares, assets, receiver, owner] - __EVENT_HASH(Withdraw) // [event_hash, msg.sender, assets, owner, shares, assets, receiver, owner] - 0x40 0x00 log4 // [shares, assets, receiver, owner] - - // Store the transfer selector in memory - __FUNC_SIG(transfer) // [selector, shares, assets, receiver, owner] - 0xE0 shl // [selector, shares, assets, receiver, owner] - 0x00 mstore // [shares, assets, receiver, owner] - - // Store the receiver in memory as the first arg - dup3 0x04 mstore // [shares, assets, receiver, owner] - - // Store this address as the second call argument in memory - dup2 0x24 mstore // [shares, assets, receiver, owner] - - // Load asset from storage - _GET_IMMUTABLE(ASSET_OFFSET, 0x80) // [asset, shares, assets, receiver, owner] - - // Construct the call - 0x00 // [retSize, asset, shares, assets, receiver, owner] - 0x00 // [retOffset, retSize, asset, shares, assets, receiver, owner] - 0x44 // [argSize, retOffset, retSize, asset, shares, assets, receiver, owner] - 0x00 // [argOffset, argSize, retOffset, retSize, asset, shares, assets, receiver, owner] - 0x00 // [value, argOffset, argSize, retOffset, retSize, asset, shares, assets, receiver, owner] - dup6 // [to, value, argOffset, argSize, retOffset, retSize, asset, shares, assets, receiver, owner] - gas // [gas, to, value, argOffset, argSize, retOffset, retSize, asset, shares, assets, receiver, owner] - call // [success, asset, shares, assets, receiver, owner] - - // Verify the call succeeded - success jumpi // [asset, shares, assets, receiver, owner] - 0x00 dup1 revert // [] - success: - - // Return shares - pop // [shares, assets, receiver, owner] - swap3 pop pop pop // [shares] -} - - -// ------------------------------------------------------ -// ACCOUNTING LOGIC -// ------------------------------------------------------ - -// Input Stack: [] -// Output Stack: [total_assets] -/// @notice Returns the total amount of assets in the Vault -/// @notice REQUIRES OVERRIDEN IMPLEMENTATION -// #define macro TOTAL_ASSETS_INNER() = takes (0) returns (1) - -/// @notice Returns the total amount of assets in the Vault -#define macro TOTAL_ASSETS() = takes (0) returns (0) { - TOTAL_ASSETS_INNER() // [total_assets] - 0x00 mstore // [] - 0x20 0x00 return // [] -} - -/// @notice Returns the amount of assets needed to mint the given amount of shares -/// @param {shares} [uint256] The amount of shares to mint -#define macro PREVIEW_MINT() = takes (0) returns (0) { - 0x04 calldataload // [shares] - PREVIEW_MINT_INNER() // [assets] - 0x00 mstore // [] - 0x20 0x00 return // [] -} - -#define macro PREVIEW_MINT_INNER() = takes (1) returns (1) { - // Input Stack: [shares] - // Output Stack: [assets] - - // Load the total supply - [TOTAL_SUPPLY_SLOT] sload // [supply, shares] - - // Return shares if supply is zero - dup1 calculate jumpi // [supply, shares] - pop cont jump // [] - - // Otherwise mul div up - calculate: - - swap1 // [shares, supply] - TOTAL_ASSETS_INNER() swap1 // [shares, total_assets, supply] - MUL_DIV_UP(fail) // [shares] - cont jump - - // Fail with an arithmetic overflow - fail: - [ARITHMETIC_OVERFLOW] PANIC() - - // Resume withdrawal with share count - cont: // [assets] -} - -/// @notice Calculates the amount of shares that would be exchanged for a given amount of assets -/// @param {assets} [uint256] The amount of assets to exchange -#define macro PREVIEW_DEPOSIT() = takes (1) returns (1) { - 0x04 calldataload // [assets] - PREVIEW_DEPOSIT_INNER() // [shares] - 0x00 mstore // [] - 0x20 0x00 return // [] -} - -#define macro PREVIEW_DEPOSIT_INNER() = takes (1) returns (1) { - CONVERT_TO_SHARES_INNER() // [shares] -} - -/// @notice Converts assets to shares -/// @param {assets} [uint256] The amount of assets to convert -#define macro CONVERT_TO_SHARES() = takes (0) returns (0) { - 0x04 calldataload // [assets] - CONVERT_TO_SHARES_INNER() // [shares] - 0x00 mstore // [] - 0x20 0x00 return // [] -} - -#define macro CONVERT_TO_SHARES_INNER() = takes (1) returns (1) { - // Input Stack: [assets] - // Output Stack: [shares] - - [TOTAL_SUPPLY_SLOT] sload // [supply, assets] - - // Return assets if supply is zero - dup1 calculate jumpi // [supply, assets] - pop cont jump // [] - - // Otherwise mul div down - calculate: - - TOTAL_ASSETS_INNER() swap2 // [assets, supply, total_assets] - MUL_DIV_DOWN(fail) // [shares] - cont jump - - // Fail with an arithmetic overflow - fail: - [ARITHMETIC_OVERFLOW] PANIC() - - // Resume withdrawal with share count - cont: // [shares] -} - -/// @notice Converts shares to assets -/// @param {shares} [uint256] The amount of shares to convert -#define macro CONVERT_TO_ASSETS() = takes (0) returns (0) { - 0x04 calldataload // [shares] - CONVERT_TO_ASSETS_INNER() // [assets] - 0x00 mstore // [] - 0x20 0x00 return // [] -} - -#define macro CONVERT_TO_ASSETS_INNER() = takes (1) returns (1) { - // Input Stack: [shares] - // Output Stack: [assets] - - [TOTAL_SUPPLY_SLOT] sload // [supply, shares] - - // Return assets if supply is zero - dup1 calculate jumpi // [supply, shares] - pop cont jump // [] - - // Otherwise mul div down - calculate: - - swap1 // [shares, supply] - TOTAL_ASSETS_INNER() swap1 // [shares, total_assets, supply] - MUL_DIV_DOWN(fail) // [assets] - cont jump - - // Fail with an arithmetic overflow - fail: - [ARITHMETIC_OVERFLOW] PANIC() - - // Resume withdrawal with share count - cont: // [assets] -} - -/// @notice Calculates the amount of shares that would be exchanged for a given amount of assets -/// @param {assets} [uint256] The amount of assets to exchange -#define macro PREVIEW_WITHDRAW() = takes (1) returns (1) { - 0x04 calldataload // [assets] - PREVIEW_WITHDRAW_INNER() // [shares] - 0x00 mstore // [] - 0x20 0x00 return // [] -} - -#define macro PREVIEW_WITHDRAW_INNER() = takes (1) returns (1) { - // Input Stack: [assets] - // Output Stack: [shares] - - [TOTAL_SUPPLY_SLOT] sload // [supply, assets] - - // Return assets if supply is zero - dup1 calculate jumpi // [supply, assets] - pop dont_fail jump // [] - - // Otherwise mul div up - calculate: - - TOTAL_ASSETS_INNER() swap2 // [assets, supply, total_assets] - MUL_DIV_UP(fail) // [shares] - dont_fail jump - - // Fail with an arithmetic overflow - fail: - [ARITHMETIC_OVERFLOW] PANIC() - - // Resume withdrawal with share count - dont_fail: // [shares] -} - -/// @notice Calculates the amount of assets that would be exchanged for a given amount of shares on redemption -/// @param {shares} [uint256] The amount of shares to exchange -#define macro PREVIEW_REDEEM() = takes (0) returns (0) { - 0x04 calldataload // [shares] - CONVERT_TO_ASSETS_INNER() // [assets] - 0x00 mstore // [] - 0x20 0x00 return // [] -} - -// ------------------------------------------------------ -// DEPOSIT/WITHDRAWAL LIMIT LOGIC -// ------------------------------------------------------ - -/// @notice Max Deposit -/// @notice Returns the maximum amount of assets available to deposit -#define macro MAX_DEPOSIT() = takes (0) returns (0) { - [TYPE_UINT_256_MAX] // [type(uint256).max] - 0x00 mstore // [] - 0x20 0x00 return // [] -} - -/// @notice Max Mint -/// @notice Returns the maximum amount of shares available to mint -#define macro MAX_MINT() = takes (0) returns (0) { - [TYPE_UINT_256_MAX] // [type(uint256).max] - 0x00 mstore // [] - 0x20 0x00 return // [] -} - -/// @notice Max Withdraw -/// @notice Returns the maximum amount of assets available to withdraw -/// @param {owner} [address] The address of the account to withdraw assets from -#define macro MAX_WITHDRAW() = takes (0) returns (0) { - 0x04 calldataload // [owner] - [BALANCE_SLOT] sload // [balanceOf[owner]] - CONVERT_TO_ASSETS_INNER() // [assets] - 0x00 mstore // [] - 0x20 0x00 return // [] -} - -/// @notice Max Redeem -/// @notice Returns the maximum amount of shares available to redeem -/// @param {owner} [address] The address of the account to redeem shares from -#define macro MAX_REDEEM() = takes (0) returns (0) { - 0x04 calldataload // [owner] - [BALANCE_SLOT] sload // [balanceOf[owner]] - 0x00 mstore // [] - 0x20 0x00 return // [] -} - -// ------------------------------------------------------ -// INTERNAL HOOKS LOGIC -// ------------------------------------------------------ - -// Input Stack: [assets, shares] -// Output Stack: [] -/// @notice Called before a withdrawal -/// @notice REQUIRES OVERRIDEN IMPLEMENTATION -// #define macro BEFORE_WITHDRAW() = takes (2) returns (0) - -// Input Stack: [assets, shares] -// Output Stack: [] -/// @notice Called after a deposit -/// @notice REQUIRES OVERRIDEN IMPLEMENTATION -// #define macro AFTER_DEPOSIT() = takes (2) returns (0) - -// ------------------------------------------------------ -// DISPATCH LOGIC -// ------------------------------------------------------ - -/// @notice An internal function dispatcher -#define macro ERC4626_MAIN() = takes (1) returns (1) { - // Input stack: [func_selector] - // Output stack: [func_selector] - - dup1 __FUNC_SIG(decimals) eq decimals_jump jumpi // [func_selector] - dup1 __FUNC_SIG(asset) eq asset_jump jumpi // [func_selector] - - dup1 __FUNC_SIG(deposit) eq deposit_jump jumpi // [func_selector] - dup1 __FUNC_SIG(withdraw) eq withdraw_jump jumpi // [func_selector] - dup1 __FUNC_SIG(mint) eq mint_jump jumpi // [func_selector] - dup1 __FUNC_SIG(redeem) eq redeem_jump jumpi // [func_selector] - - dup1 __FUNC_SIG(totalAssets) eq total_assets_jump jumpi // [func_selector] - dup1 __FUNC_SIG(convertToShares) eq convert_to_shares_jump jumpi // [func_selector] - dup1 __FUNC_SIG(convertToAssets) eq convert_to_assets_jump jumpi // [func_selector] - dup1 __FUNC_SIG(previewDeposit) eq preview_deposit_jump jumpi // [func_selector] - dup1 __FUNC_SIG(previewMint) eq preview_mint_jump jumpi // [func_selector] - dup1 __FUNC_SIG(previewWithdraw) eq preview_withdraw_jump jumpi // [func_selector] - dup1 __FUNC_SIG(previewRedeem) eq preview_redeem_jump jumpi // [func_selector] - - dup1 __FUNC_SIG(maxDeposit) eq max_deposit_jump jumpi // [func_selector] - dup1 __FUNC_SIG(maxMint) eq max_mint_jump jumpi // [func_selector] - dup1 __FUNC_SIG(maxWithdraw) eq max_withdraw_jump jumpi // [func_selector] - dup1 __FUNC_SIG(maxRedeem) eq max_redeem_jump jumpi // [func_selector] - - ERC20_MAIN() // [func_selector] - - // Bubble up to the parent macro - no_match jump - - decimals_jump: - ERC4626_DECIMALS() - asset_jump: - ERC4626_ASSET() - - deposit_jump: - ERC4626_DEPOSIT() - withdraw_jump: - ERC4626_WITHDRAW() - mint_jump: - ERC4626_MINT() - redeem_jump: - ERC4626_REDEEM() - - total_assets_jump: - TOTAL_ASSETS() - convert_to_shares_jump: - CONVERT_TO_SHARES() - convert_to_assets_jump: - CONVERT_TO_ASSETS() - preview_deposit_jump: - PREVIEW_DEPOSIT() - preview_mint_jump: - PREVIEW_MINT() - preview_withdraw_jump: - PREVIEW_WITHDRAW() - preview_redeem_jump: - PREVIEW_REDEEM() - - max_deposit_jump: - MAX_DEPOSIT() - max_mint_jump: - MAX_MINT() - max_withdraw_jump: - MAX_WITHDRAW() - max_redeem_jump: - MAX_REDEEM() - - // Resume parent dispatching - no_match: // [func_selector] -} diff --git a/src/tokens/__TEMP__vvaewlzfkyljuiwoxdrktdnlhsuzsmbhERC721.huff b/src/tokens/__TEMP__vvaewlzfkyljuiwoxdrktdnlhsuzsmbhERC721.huff deleted file mode 100644 index 17f4c60b..00000000 --- a/src/tokens/__TEMP__vvaewlzfkyljuiwoxdrktdnlhsuzsmbhERC721.huff +++ /dev/null @@ -1,787 +0,0 @@ - -#define function mint(address, uint256) payable returns () -#define function burn(uint256) nonpayable returns () - -#define function mint(address, uint256) payable returns () -#define function burn(uint256) nonpayable returns () - -#define function safeMint(address to, uint256 tokenId, bytes memory data) payable returns () -#define function safeMint(address to, uint256 tokenId) payable returns () - -#define macro CONSTRUCTOR() = takes (0) returns (0) { - ERC721_CONSTRUCTOR() -} - -#define macro MINT() = takes (0) returns (0) { - 0x24 calldataload // [tokenId] - 0x04 calldataload // [to, tokenId] - _MINT() - stop -} - -#define macro BURN() = takes (0) returns (0) { - 0x04 calldataload // [tokenId] - _BURN() - stop -} - -#define macro SAFE_MINT() = takes (0) returns (0) { - 0x24 calldataload // [tokenId] - 0x04 calldataload // [to, tokenId] - _MINT() - - // Safe Logic - // Make sure we can transfer to the recipient - 0x04 calldataload // [to] - dup1 extcodesize // [to.code.length, to] - iszero safe jumpi // [to] - - // onERC721Received Selector - 0x150b7a02 dup1 // [onERC721Received, onERC721Received, to] - 0xE0 shl // [onERC721Received_shifted, onERC721Received, to] - - // Store the left-shifted selector for call - 0x20 mstore // [onERC721Received, to] - - // Store the msg.sender as the first arg - caller 0x24 mstore // [onERC721Received, to] - - // Store address(0) as the second arg - 0x00 // [address(0), onERC721Received, to] - 0x44 mstore // [onERC721Received, to] - - // Id is the third arg - 0x24 calldataload // [tokenId, onERC721Received, to] - 0x64 mstore // [onERC721Received, to] - - // Blank bytes array as 4th arg (no data) - 0x80 0x84 mstore - 0x00 0xA4 mstore - - // Call address(to).onERC721Received(msg.sender, from, tokenId, "") - 0x20 // [retSize, onERC721Received, to] - 0x00 // [retOffset, retSize, onERC721Received, to] - 0xA4 // [argSize, retOffset, retSize, onERC721Received, to] - dup3 // [argOffset, argSize, retOffset, retSize, onERC721Received, to] - dup3 // [value, argOffset, argSize, retOffset, retSize, onERC721Received, to] - dup7 // [to, value, argOffset, argSize, retOffset, retSize, onERC721Received, to] - gas // [gas, to, value, argOffset, argSize, retOffset, retSize, onERC721Received, to] - call // [success, onERC721Received, to] - - // Revert if call isn't successful - cont jumpi // [onERC721Received, to] - 0x00 dup1 revert - cont: - - // Compare the return data to the onERC721Received selector - 0x00 mload 0xE0 shr // [response, onERC721Received, to] - eq safe jumpi // [to] - - // Revert if the return data is not accepted - UNSAFE_RECIPIENT(0x00) - - // Stop execution if safe - safe: - stop -} - -#define macro SAFE_MINT_WITH_DATA() = takes (0) returns (0) { - 0x44 calldataload // [data] - 0x24 calldataload // [tokenId, data] - 0x04 calldataload // [to, tokenId, data] - _MINT() - - // Make sure we can transfer to the recipient - 0x04 calldataload // [to] - dup1 extcodesize // [to.code.length, to] - iszero safe jumpi // [to] - - // onERC721Received Selector - 0x150b7a02 dup1 // [onERC721Received, onERC721Received, to] - 0xE0 shl // [onERC721Received_shifted, onERC721Received, to] - - // Store the left-shifted selector for call - 0x20 mstore // [onERC721Received, to] - - // Store the msg.sender as the first arg - caller 0x24 mstore // [onERC721Received, to] - - // Store address(0) as the second arg - 0x00 // [address(0), onERC721Received, to] - 0x44 mstore // [onERC721Received, to] - - // Id is the third arg - 0x24 calldataload // [tokenId, onERC721Received, to] - 0x64 mstore // [onERC721Received, to] - - // Store the pointer to the data length - 0x80 0x84 mstore // [onERC721Received, to] - - 0x64 calldataload // [len(data), onERC721Received, to] - 0x05 shl // [len(data) * 0x20, onERC721Received, to] - 0x20 add // [len(data) * 0x20 + 0x20, onERC721Received, to] - dup1 // [len(data) * 0x20 + 0x20, len(data) * 0x20 + 0x20, onERC721received, to] - 0x64 // [0x64, len(data) * 0x20 + 0x20, len(data) * 0x20 + 0x20, onERC721received, to] - 0xA4 // [0x84, 0x64, len(data) * 0x20 + 0x20, len(data) * 0x20 + 0x20, onERC721received, to] - calldatacopy // [len(bytes), onERC721received, to] - - // Call address(to).onERC721Received(msg.sender, from, tokenId, bytes) - 0x20 // [retSize, len(bytes), onERC721Received, to] - 0x00 // [retOffset, retSize, len(bytes), onERC721Received, to] - swap1 swap2 // [len(bytes), retOffset, retSize, onERC721Received, to] - 0x84 add // [argSize, retOffset, retSize, onERC721Received, to] - dup3 // [argOffset, argSize, retOffset, retSize, len(bytes), onERC721Received, to] - dup3 // [value, argOffset, argSize, retOffset, retSize, len(bytes), onERC721Received, to] - dup7 // [to, value, argOffset, argSize, retOffset, retSize, len(bytes), onERC721Received, to] - gas // [gas, to, value, argOffset, argSize, retOffset, retSize, len(bytes), onERC721Received, to] - call // [success, len(bytes), onERC721Received, to] - - // Revert if call isn't successful - selector_call_success jumpi // [len(bytes), onERC721Received, to] - 0x00 dup1 revert - selector_call_success: - - // Compare the return data to the onERC721Received selector - 0x00 mload 0xE0 shr // [response, onERC721Received, to] - eq safe jumpi // [to] - - // Revert if the return data is not accepted - UNSAFE_RECIPIENT(0x00) - - // Stop execution if safe - safe: - stop - -} - -// Function Dispatch -#define macro MAIN() = takes (0) returns (0) { - 0x00 calldataload 0xE0 shr // [sig] - - // Mint and Burning Functions - dup1 __FUNC_SIG(mint) eq mint_jump jumpi - dup1 __FUNC_SIG(burn) eq burn_jump jumpi - - dup1 __FUNC_SIG("safeMint(address,uint256)") eq safe_mint jumpi - dup1 __FUNC_SIG("safeMint(address,uint256,bytes)") eq safe_mint_with_data jumpi - - dup1 __FUNC_SIG(approve) eq approve jumpi - dup1 __FUNC_SIG(setApprovalForAll) eq setApprovalForAll jumpi - - dup1 __FUNC_SIG(transferFrom) eq transferFrom jumpi - dup1 __FUNC_SIG(safeTransferFrom) eq safeTransferFrom jumpi - - dup1 __FUNC_SIG(name) eq name jumpi - dup1 __FUNC_SIG(symbol) eq symbol jumpi - dup1 __FUNC_SIG(tokenURI) eq tokenURI jumpi - dup1 __FUNC_SIG(supportsInterface) eq supportsInterface jumpi - - dup1 __FUNC_SIG(getApproved) eq getApproved jumpi - dup1 __FUNC_SIG(isApprovedForAll) eq isApprovedForAll jumpi - - dup1 __FUNC_SIG(balanceOf) eq balanceOf jumpi - dup1 __FUNC_SIG(ownerOf) eq ownerOf jumpi - - dup1 __FUNC_SIG("safeTransferFrom(address,address,uint256,bytes)") eq safeTransferFromData jumpi - - // Revert on failed dispatch - 0x00 dup1 revert - - safe_mint: - SAFE_MINT() - safe_mint_with_data: - SAFE_MINT_WITH_DATA() - - mint_jump: - MINT() - burn_jump: - BURN() - - approve: - APPROVE() - setApprovalForAll: - SET_APPROVAL_FOR_ALL() - - transferFrom: - TRANSFER_FROM() - safeTransferFrom: - SAFE_TRANSFER_FROM() - safeTransferFromData: - SAFE_TRANSFER_FROM_WITH_DATA() - - name: - NAME() - symbol: - SYMBOL() - tokenURI: - TOKEN_URI() - supportsInterface: - SUPPORTS_INTERFACE() - - getApproved: - GET_APPROVED() - isApprovedForAll: - IS_APPROVED_FOR_ALL() - - balanceOf: - BALANCE_OF() - ownerOf: - OWNER_OF() -} - - -/// @title ERC721 -/// @notice SPDX-License-Identifier: MIT -/// @author asnared -/// @author kadenzipfel -/// @notice Modern and heavily gas golfed ERC-721 implementation -/// @notice Adapted from Solmate https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC721.sol - -// Imports -#include "../utils/CommonErrors.huff" -#include "../auth/NonPayable.huff" -#include "../data-structures/Hashmap.huff" - -// Interface -#define function name() nonpayable returns (string) -#define function symbol() nonpayable returns (string) -#define function tokenURI(uint256) nonpayable returns (string) - -#define function mint(address, uint256) payable returns () -#define function burn(uint256) nonpayable returns () - -#define function transfer(address,uint256) nonpayable returns () -#define function transferFrom(address,address,uint256) nonpayable returns () -#define function safeTransferFrom(address,address,uint256) nonpayable returns () -#define function safeTransferFrom(address,address,uint256,bytes) nonpayable returns () - -#define function approve(address,uint256) nonpayable returns () -#define function setApprovalForAll(address,bool) nonpayable returns () - -#define function getApproved(uint256) view returns (address) -#define function isApprovedForAll(address,address) view returns (bool) -#define function ownerOf(uint256) view returns (address) -#define function balanceOf(address) view returns (uint256) -#define function supportsInterface(bytes4) view returns (bool) - -// Events -#define event Transfer(address,address,uint256) -#define event Approval(address,address,uint256) -#define event ApprovalForAll(address,address,bool) - -// Storage Slots -#define constant OWNER_LOCATION = FREE_STORAGE_POINTER() -#define constant BALANCE_LOCATION = FREE_STORAGE_POINTER() -#define constant SINGLE_APPROVAL_LOCATION = FREE_STORAGE_POINTER() - -// Immutables offsets -#define constant NAME_OFFSET = 0x0000000000000000000000000000000000000000000000000000000000000080 -#define constant NAME_LENGTH_OFFSET = 0x00000000000000000000000000000000000000000000000000000000000000a0 -#define constant SYMBOL_OFFSET = 0x0000000000000000000000000000000000000000000000000000000000000020 -#define constant SYMBOL_LENGTH_OFFSET = 0x0000000000000000000000000000000000000000000000000000000000000040 - -/// >>>>>>>>>>>>>>>>>>>>> CONSTRUCTOR <<<<<<<<<<<<<<<<<<<<<< /// - -/// @notice Constructor -#define macro ERC721_CONSTRUCTOR() = takes (0) returns (0) { - // Constructor arguments: - // ?, name_size, name, ?, symbol_size, symbol - - // This constructor will return the runtime bytecode with all the - // constructor arguments concatenated at the end. - - // Copy the runtime bytecode with constructor argument concatenated. - 0xb // [offset] - constructor code size - dup1 // [offset, offset] - codesize // [total_size, offset, offset] - sub // [runtime_size, offset] - dup1 // [runtime_size, runtime_size, offset] - swap2 // [offset, runtime_size, runtime_size] - returndatasize // [return_offset, offset, runtime_size, runtime_size] - codecopy // [runtime_size] - - // Return the runtime bytecode. - returndatasize // [return_offset, runtime_size] - return // [] -} - -/// >>>>>>>>>>>>>>>>>>>>> VIEW FUNCTIONS <<<<<<<<<<<<<<<<<<<<<< /// - -/// @notice Name -/// @notice Returns the token name string -#define macro NAME() = takes (0) returns (0) { - NON_PAYABLE() // [] - _GET_IMMUTABLE(NAME_OFFSET, 0x00) // [name_value] - _GET_IMMUTABLE(NAME_LENGTH_OFFSET, 0x00) // [name_length, name_value] - 0x20 0x00 mstore // [name_length, name_value] - 0x20 mstore // [name_value] - 0x40 mstore // [] - 0x60 0x00 return // [] -} - -/// @notice Symbol -/// @notice Returns the symbol of the token -#define macro SYMBOL() = takes (0) returns (0) { - NON_PAYABLE() // [] - _GET_IMMUTABLE(SYMBOL_OFFSET, 0x00) // [symbol_value] - _GET_IMMUTABLE(SYMBOL_LENGTH_OFFSET, 0x00) // [symbol_length, symbol_value] - 0x20 0x00 mstore // [symbol_length, symbol_value] - 0x20 mstore // [symbol_value] - 0x40 mstore // [] - 0x60 0x00 return // [] -} - -/// @notice Balance Of -/// @notice Returns the balance of the given address -#define macro BALANCE_OF() = takes (0) returns (0) { - NON_PAYABLE() // [] - 0x04 calldataload // [account] - [BALANCE_LOCATION] LOAD_ELEMENT_FROM_KEYS(0x00) // [balance] - 0x00 mstore // [] - 0x20 0x00 return // [] -} - -/// @notice Owner Of -/// @notice Returns the owner of the given token id -#define macro OWNER_OF() = takes (0) returns (0) { - 0x04 calldataload // [tokenId] - [OWNER_LOCATION] LOAD_ELEMENT_FROM_KEYS(0x00) // [owner] - 0x00 mstore // [] - 0x20 0x00 return // [] -} - -/// @notice Is Approved For All -/// @notice Returns whether the given operator is approved for all tokens of the given owner -#define macro IS_APPROVED_FOR_ALL() = takes (0) returns (0) { - 0x24 calldataload // [to] - 0x04 calldataload // [from, to] - LOAD_ELEMENT_FROM_KEYS(0x00) // [value] - 0x00 mstore // [] - 0x20 0x00 return // [] -} - -/// @notice Get Approved -/// @notice Returns the approved address for the given token id -#define macro GET_APPROVED() = takes (0) returns (0) { - 0x04 calldataload // [tokenId] - [SINGLE_APPROVAL_LOCATION] // [approval_slot, tokenId] - LOAD_ELEMENT_FROM_KEYS(0x00) // [spender] - 0x00 mstore // [] - 0x20 0x00 return // [] -} - -/// @notice Token URI -#define macro TOKEN_URI() = takes (0) returns (0) { - 0x20 0x00 mstore - 0x00 0x20 mstore - 0x40 0x00 return -} - -/// @notice Checks if the given interface is supported -#define macro SUPPORTS_INTERFACE() = takes (0) returns (0) { - // grab interfaceId - 0x04 calldataload // [interfaceId] - 0xe0 shr // [right_aligned_interfaceId] - - // Check if erc165 interfaceId - dup1 // [interfaceId, interfaceId] - 0x01ffc9a7 eq // [is_erc165, interfaceId] - is_interface jumpi - - // Check if erc721 interfaceId - dup1 // [interfaceId, interfaceId] - 0x80ac58cd eq // [is_erc721, interfaceId] - is_interface jumpi - - // Check if erc721Metadata interfaceId - 0x5b5e139f eq // [is_erc721Metadata] - is_interface jumpi - - // Return false (0x00) - 0x00 mstore // [] - 0x20 0x00 return // [] - - // Return true (0x01) - is_interface: - pop // [] - 0x01 0x00 mstore // [] - 0x20 0x00 return // [] -} - -/// >>>>>>>>>>>>>>>>>>>>> INTERNAL FUNCTIONS <<<<<<<<<<<<<<<<<<<<<< /// - -/// @notice Mint -/// @notice Mints a new token -/// @dev The Mint function is payable -#define macro _MINT() = takes (2) returns (0) { - // Input stack: // [to, tokenId] - // Output stack: // [] - - // Check that the recipient is valid - dup1 iszero invalid_recipient jumpi // [to, tokenId] - - // Create the minting params - 0x00 dup3 // [tokenId, from (0x00), to, tokenId] - - // Check token ownership - [OWNER_LOCATION] LOAD_ELEMENT_FROM_KEYS(0x00) // [owner, from (0x00), to, tokenId] - iszero iszero unauthorized jumpi - - // Give tokens to the recipient. - TRANSFER_GIVE_TO() // [from (0x00), to, tokenId] - - // Emit the transfer event. - __EVENT_HASH(Transfer) // [sig, from (0x00), to, tokenId] - 0x00 0x00 log4 // [] - - // Continue Executing - cont jump - - invalid_recipient: - INVALID_RECIPIENT(0x00) - - unauthorized: - ALREADY_MINTED(0x00) - - cont: -} - -/// @notice Burn -/// @notice Burns the token with the given id -#define macro _BURN() = takes (1) returns (0) { - // Input stack: // [tokenId] - NON_PAYABLE() // [tokenId] - - dup1 // [tokenId, tokenId] - [OWNER_LOCATION] LOAD_ELEMENT_FROM_KEYS(0x00) // [owner, tokenId] - - // Check that the recipient is valid - dup1 iszero // [owner == 0, owner, tokenId] - not_minted jumpi // [owner, tokenId] - - // Create the burning params - 0x00 swap1 // [owner, to (0x00), tokenId] - - // Reduce the balance of owner by 1 - 0x01 dup2 // [owner, 1, owner, to, tokenId] - [BALANCE_LOCATION] LOAD_ELEMENT_FROM_KEYS(0x00) // [balance, 1, owner, to, tokenId] - sub dup2 // [owner, balance-1, owner, to, tokenId] - [BALANCE_LOCATION] - STORE_ELEMENT_FROM_KEYS(0x00) // [owner, to, tokenId] - - // Set the owner of the token to 0x00 - 0x00 dup4 [OWNER_LOCATION] // [slot, owner, 0x00, owner, to, tokenId] - STORE_ELEMENT_FROM_KEYS(0x00) // [owner, to, tokenId] - - // Set the approval of the token to 0x00 for the owner - 0x00 dup4 [SINGLE_APPROVAL_LOCATION] // [slot, owner, 0x00, owner, to, tokenId] - STORE_ELEMENT_FROM_KEYS(0x00) // [owner, to, tokenId] - - // Emit the transfer event. - __EVENT_HASH(Transfer) // [sig, owner, to (0x00), tokenId] - 0x00 0x00 // [0, 0, sig, owner, to (0x00), tokenId] - log4 // [] - - // Continue Executing - cont jump - - not_minted: - NOT_MINTED(0x00) - - cont: -} - -/// @notice Retrives an "immutable" from the runtime bytecode. -#define macro _GET_IMMUTABLE(offset_end, free_memory) = takes (0) returns (1) { - 0x20 // [size] - codesize sub // [offset_code, size] - // [offset_memory, offset_code, size] - codecopy // [] - mload // [value] -} - -/// >>>>>>>>>>>>>>>>>>>>> EXTERNAL FUNCTIONS <<<<<<<<<<<<<<<<<<<<<< /// - -/// @notice Approve -/// @notice Approves a spender for a specific token -#define macro APPROVE() = takes (0) returns (0) { - // Load the token owner - 0x24 calldataload dup1 // [tokenId, tokenId] - [OWNER_LOCATION] - LOAD_ELEMENT_FROM_KEYS(0x00) // [owner, tokenId] - dup1 caller eq // [is_sender_owner, owner, tokenId] - - // Check if approved for all - caller dup3 // [owner, msg.sender, is_sender_owner, owner, tokenId] - LOAD_ELEMENT_FROM_KEYS(0x00) // [is_approved_for_all, is_sender_owner, owner, tokenId]] - or cont jumpi // [owner, tokenId] - not_authorized jump - cont: - - // Store approval - 0x04 calldataload dup1 dup4 // [tokenId, spender, spender, owner, tokenId] - [SINGLE_APPROVAL_LOCATION] - STORE_ELEMENT_FROM_KEYS(0x00) // [spender, owner, tokenId] - swap1 // [owner, spender, tokenId] - - // Emit the approval event - __EVENT_HASH(Approval) // [sig, owner, spender, tokenId] - 0x00 0x00 log4 // [] - - stop - - not_authorized: - UNAUTHORIZED(0x00) -} - -/// @notice Set Approval For All -/// @notice Sets an operator as approved for all tokens of the caller -#define macro SET_APPROVAL_FOR_ALL() = takes (0) returns (0) { - // Store the operator as approved for all - 0x24 calldataload // [approved] - 0x04 calldataload // [operator, approved] - caller // [msg.sender, operator, approved] - STORE_ELEMENT_FROM_KEYS(0x00) // [] - - // Emit the ApprovalForAll event - 0x24 calldataload // [approved] - 0x04 calldataload // [operator, approved] - caller // [msg.sender, operator, approved] - __EVENT_HASH(ApprovalForAll) // [sig, owner, operator] - 0x00 0x00 // [0, 32, sig, owner, operator] - log4 // [] - - // Stop execution - stop -} - -/// @notice Transfer From -/// @notice Transfers a token from one address to another -#define macro TRANSFER_FROM() = takes (0) returns (0) { - // Setup the stack for the transfer function. - 0x44 calldataload // [tokenId] - 0x24 calldataload // [to, tokenId] - 0x04 calldataload // [from, to, tokenId] - - // Accounting Logic - TRANSFER_TAKE_FROM() // [from, to, tokenId] - TRANSFER_GIVE_TO() // [from, to, tokenId] - - // Emit the transfer event - __EVENT_HASH(Transfer) // [sig,from, to, tokenId] - 0x20 0x00 log4 // [] - - // Stop execution - stop -} - -/// @notice Safe Transfer From -#define macro SAFE_TRANSFER_FROM() = takes (0) returns (0) { - // Setup the stack for the transfer function. - 0x44 calldataload // [tokenId] - 0x24 calldataload // [to, tokenId] - 0x04 calldataload // [from, to, tokenId] - - TRANSFER_TAKE_FROM() // [from, to, tokenId] - TRANSFER_GIVE_TO() // [from, to, tokenId] - - // Emit the transfer event - __EVENT_HASH(Transfer) // [sig, from, to, tokenId] - 0x00 0x00 log4 // [] - - // Make sure we can transfer to the recipient - 0x24 calldataload // [to] - dup1 extcodesize // [to.code.length, to] - iszero safe jumpi // [to] - - // onERC721Received Selector - 0x150b7a02 dup1 // [onERC721Received, onERC721Received, to] - 0xE0 shl // [onERC721Received_shifted, onERC721Received, to] - - // Store the left-shifted selector for call - 0x20 mstore // [onERC721Received, to] - - // Store the msg.sender as the first arg - caller 0x24 mstore // [onERC721Received, to] - - // Store from as the second arg - 0x04 calldataload // [from, onERC721Received, to] - 0x44 mstore // [onERC721Received, to] - - // Id is the third arg - 0x44 calldataload // [tokenId, onERC721Received, to] - 0x64 mstore // [onERC721Received, to] - - // Blank bytes array as 4th arg (no data) - 0x80 0x84 mstore - 0x00 0xA4 mstore - - // Call address(to).onERC721Received(msg.sender, from, tokenId, "") - 0x20 // [retSize, onERC721Received, to] - 0x00 // [retOffset, retSize, onERC721Received, to] - 0xA4 // [argSize, retOffset, retSize, onERC721Received, to] - dup3 // [argOffset, argSize, retOffset, retSize, onERC721Received, to] - dup3 // [value, argOffset, argSize, retOffset, retSize, onERC721Received, to] - dup7 // [to, value, argOffset, argSize, retOffset, retSize, onERC721Received, to] - gas // [gas, to, value, argOffset, argSize, retOffset, retSize, onERC721Received, to] - call // [success, onERC721Received, to] - - // Revert if call isn't successful - cont jumpi // [onERC721Received, to] - 0x00 dup1 revert - cont: - - // Compare the return data to the onERC721Received selector - 0x00 mload 0xE0 shr // [response, onERC721Received, to] - eq safe jumpi // [to] - - // Revert if the return data is not accepted - UNSAFE_RECIPIENT(0x00) - - // Stop execution if safe - safe: - stop -} - -#define macro SAFE_TRANSFER_FROM_WITH_DATA() = takes (0) returns (0) { - // Setup the stack for the transfer function. - 0x44 calldataload // [tokenId] - 0x24 calldataload // [to, tokenId] - 0x04 calldataload // [from, to, tokenId] - - TRANSFER_TAKE_FROM() // [from, to, tokenId] - TRANSFER_GIVE_TO() // [from, to, tokenId] - - // Emit the transfer event. - __EVENT_HASH(Transfer) // [sig, from, to, tokenId] - 0x00 0x00 log4 // [] - - // Make sure we can transfer to the recipient - 0x24 calldataload // [to] - dup1 extcodesize // [to.code.length, to] - iszero safe jumpi // [to] - - // onERC721Received Selector - 0x150b7a02 dup1 // [onERC721Received, onERC721Received, to] - 0xE0 shl // [onERC721Received_shifted, onERC721Received, to] - - // Store the left-shifted selector for call - 0x20 mstore // [onERC721Received, to] - - // Store the msg.sender as the first arg - caller 0x24 mstore // [onERC721Received, to] - - // Store from as the second arg - 0x04 calldataload // [from, onERC721Received, to] - 0x44 mstore // [onERC721Received, to] - - // Id is the third arg - 0x44 calldataload // [tokenId, onERC721Received, to] - 0x64 mstore // [onERC721Received, to] - - 0x84 calldataload // [len(data), onERC721Received, to] - 0x05 shl // [len(data) * 0x20, onERC721Received, to] - 0x40 add // [len(data) * 0x20 + 0x40, onERC721Received, to] - dup1 // [len(data) * 0x20 + 0x40, len(data) * 0x20 + 0x40, onERC721received, to] - 0x64 // [0x64, len(data) * 0x20 + 0x40, len(data) * 0x20 + 0x40, onERC721received, to] - 0x84 // [0x20, 0x64, len(data) * 0x20 + 0x40, len(data) * 0x20 + 0x40, onERC721received, to] - calldatacopy // [len(bytes), onERC721received, to] - - // Call address(to).onERC721Received(msg.sender, from, tokenId, bytes) - 0x20 // [retSize, len(bytes), onERC721Received, to] - 0x00 // [retOffset, retSize, len(bytes), onERC721Received, to] - swap1 swap2 // [len(bytes), retOffset, retSize, onERC721Received, to] - 0x64 add // [argSize, retOffset, retSize, onERC721Received, to] - dup3 // [argOffset, argSize, retOffset, retSize, len(bytes), onERC721Received, to] - dup3 // [value, argOffset, argSize, retOffset, retSize, len(bytes), onERC721Received, to] - dup7 // [to, value, argOffset, argSize, retOffset, retSize, len(bytes), onERC721Received, to] - gas // [gas, to, value, argOffset, argSize, retOffset, retSize, len(bytes), onERC721Received, to] - call // [success, len(bytes), onERC721Received, to] - - // Revert if call isn't successful - cont jumpi // [len(bytes), onERC721Received, to] - 0x00 dup1 revert - cont: - - // Compare the return data to the onERC721Received selector - 0x00 mload 0xE0 shr // [response, onERC721Received, to] - eq safe jumpi // [to] - - // Revert if the return data is not accepted - UNSAFE_RECIPIENT(0x00) - - // Stop execution if safe - safe: - stop -} - -/// >>>>>>>>>>>>>>>>>>>>> INTERNAL HELPERS <<<<<<<<<<<<<<<<<<<<<< /// - -/// @notice Internal Macro to update Transfer from accounting -#define macro TRANSFER_TAKE_FROM() = takes (3) returns (3) { - // Input stack: [from, to, tokenId] - - // If from !== ownerOf[tokenId] revert with "WRONG_FROM" - dup1 dup4 // [tokenId, from, from, to, tokenId] - [OWNER_LOCATION] LOAD_ELEMENT_FROM_KEYS(0x00) // [owner, from, from, to, tokenId] - eq cont jumpi // [from, to, tokenId] - WRONG_FROM(0x00) - cont: - - // If to === address(0) revert with "INVALID_RECIPIENT" - dup2 iszero iszero continue jumpi // [from, to, tokenId] - INVALID_RECIPIENT(0x00) - continue: - - // Check if msg.sender == from - dup1 caller eq // [msg.sender == from, from, to, tokenId] - is_authorized jumpi // [from, to, tokenId] - - // Check if approved for all - caller dup2 // [from, msg.sender, from, to, tokenId] - LOAD_ELEMENT_FROM_KEYS(0x00) // [is_approved_for_all, from, to, tokenId] - is_authorized jumpi // [from, to, tokenId] - - // Check if approved for tokenId - dup3 // [tokenId, from, to, tokenId] - [SINGLE_APPROVAL_LOCATION] // [SINGLE_APPROVAL_LOCATION, tokenId, from, to, tokenId] - LOAD_ELEMENT_FROM_KEYS(0x00) // [address_approved_for_tokenId, from, to, tokenId] - caller eq is_authorized jumpi // [from, to, tokenId] - - // If msg.sender != from && !isApprovedForAll[from][msg.sender] && msg.sender != getApproved[id], - UNAUTHORIZED(0x00) - - is_authorized: - - // Update balance of from - 0x01 dup2 // [from, 1, from, to, tokenId] - [BALANCE_LOCATION] LOAD_ELEMENT_FROM_KEYS(0x00) // [balance, 1, from, to, tokenId] - sub dup2 // [from, balance-1, from, to, tokenId] - [BALANCE_LOCATION] - STORE_ELEMENT_FROM_KEYS(0x00) // [from, to, tokenId] -} - -/// @notice Internal Macro to update Transfer to accounting -#define macro TRANSFER_GIVE_TO() = takes (3) returns (3) { - // retrieve balance - // input stack: // [from, to, tokenId] - dup2 // [to, from, to, tokenId] - [BALANCE_LOCATION] // [balance_slot, to, from, to, tokenId] - LOAD_ELEMENT_FROM_KEYS(0x00) // [balance, from, to, tokenId] - 0x01 add // [balance+1, from, to, tokenId] - - // update balance - dup3 // [to, balance+1, from, to, tokenId] - [BALANCE_LOCATION] // [balance_slot, to, balance+1, from, to, tokenId] - STORE_ELEMENT_FROM_KEYS(0x00) // [from, to, tokenId] - - // update ownerOf - dup2 dup4 // [tokenId, to, from, to, tokenId] - [OWNER_LOCATION] // [owner_slot, tokenId, to, from, to, tokenId] - STORE_ELEMENT_FROM_KEYS(0x00) // [from, to, tokenId] - - // update approval - 0x00 dup4 // [tokenId, address(0), from, to, tokenId] - [SINGLE_APPROVAL_LOCATION] // [approval_slot, tokenId, address(0), from, to, tokenId] - STORE_ELEMENT_FROM_KEYS(0x00) // [from, to, tokenId] -} diff --git a/src/tokens/__TEMP__zxgqnylgrbytfwvkvdnlnpcvxmcecsliERC4626.huff b/src/tokens/__TEMP__zxgqnylgrbytfwvkvdnlnpcvxmcecsliERC4626.huff deleted file mode 100644 index 5e3a3cbb..00000000 --- a/src/tokens/__TEMP__zxgqnylgrbytfwvkvdnlnpcvxmcecsliERC4626.huff +++ /dev/null @@ -1,859 +0,0 @@ - -#define function beforeWithdrawHookCalledCounter() nonpayable returns (uint256) -#define function afterDepositHookCalledCounter() nonpayable returns (uint256) - -#define constant BEFORE_HOOK_COUNTER = FREE_STORAGE_POINTER() -#define constant AFTER_HOOK_COUNTER = FREE_STORAGE_POINTER() - -#define macro CONSTRUCTOR() = takes (0) returns (0) { - ERC4626_CONSTRUCTOR() // [] -} - -#define macro BEFORE_WITHDRAW() = takes (2) returns (0) { - // Input Stack: [assets, shares] - // Output Stack: [] - pop pop // [] - [BEFORE_HOOK_COUNTER] sload // [counter] - 0x01 add // [counter + 1] - [BEFORE_HOOK_COUNTER] sstore // [] -} - -#define macro AFTER_DEPOSIT() = takes (2) returns (0) { - // Input Stack: [assets, shares] - // Output Stack: [] - pop pop // [] - [AFTER_HOOK_COUNTER] sload // [counter] - 0x01 add // [counter + 1] - [AFTER_HOOK_COUNTER] sstore // [] -} - -#define macro READ_BEFORE_HOOK_COUNTER() = takes (0) returns (0) { - [BEFORE_HOOK_COUNTER] sload // [counter] - 0x00 mstore // [] - 0x20 0x00 return // [] -} - -#define macro READ_AFTER_HOOK_COUNTER() = takes (0) returns (0) { - [AFTER_HOOK_COUNTER] sload // [counter] - 0x00 mstore // [] - 0x20 0x00 return // [] -} - -#define macro TOTAL_ASSETS_INNER() = takes (0) returns (1) { - // Input Stack: [] - // Output Stack: [total_assets] - - // Store the asset.balanceOf(address(this)) args in memory - __FUNC_SIG(balanceOf) - 0xE0 shl - 0x20 mstore - address 0x24 mstore - - // Get the asset variable - _GET_IMMUTABLE(ASSET_OFFSET, 0x80) // [asset] - - // Construct the call - 0x20 // [retSize, asset] - 0x00 // [retOffset, retSize, asset] - 0x24 // [argSize, retOffset, retSize, asset] - 0x20 // [argOffset, argSize, retOffset, retSize, asset] - 0x00 // [value, argOffset, argSize, retOffset, retSize, asset] - dup6 // [to, value, argOffset, argSize, retOffset, retSize, asset] - gas // [gas, to, value, argOffset, argSize, retOffset, retSize, asset] - call // [success, asset] - - // Verify the call succeeded - iszero iszero success jumpi // [asset] - 0x00 dup1 revert // [] - success: - - // Since the returndata is copied to [0x00:0x20], we can just mload - pop 0x00 mload // [total_assets] -} - - -#define macro MAIN() = takes (0) returns (0) { - pc calldataload 0xE0 shr // [sig] - - dup1 __FUNC_SIG(beforeWithdrawHookCalledCounter) eq before_jump jumpi // [sig] - dup1 __FUNC_SIG(afterDepositHookCalledCounter) eq after_jump jumpi // [sig] - - ERC4626_MAIN() // [sig] - - 0x00 dup1 revert - - before_jump: - READ_BEFORE_HOOK_COUNTER() - after_jump: - READ_AFTER_HOOK_COUNTER() -} - - -/// @title ERC4626 -/// @notice SPDX-License-Identifier: MIT -/// @author asnared -/// @notice Minimal ERC4626 tokenized Vault implementation. -/// @notice Adapted from Solmate (https://github.com/transmissions11/solmate/blob/main/src/mixins/ERC4626.sol) - -// ERC4626 is ERC20 -#include "./ERC20.huff" -#include "../utils/CommonErrors.huff" -#include "../math/FixedPointMath.huff" - -// Events -#define event Deposit(address indexed caller, address indexed owner, uint256 assets, uint256 shares) -#define event Withdraw(address indexed caller, address indexed receiver, address indexed owner, uint256 assets, uint256 shares) - -// Interface -#define function asset() view returns (address) - -#define function deposit(uint256 assets, address receiver) payable returns (uint256 shares) -#define function withdraw(uint256 assets, address receiver, address owner) payable returns (uint256 shares) -#define function mint(uint256 shares, address receiver) payable returns (uint256 assets) -#define function redeem(uint256 shares, address receiver, address owner) payable returns (uint256 assets) - -#define function totalAssets() view returns (uint256) -#define function convertToShares(uint256 assets) view returns (uint256) -#define function convertToAssets(uint256 shares) view returns (uint256) -#define function previewDeposit(uint256 assets) view returns (uint256) -#define function previewMint(uint256 shares) view returns (uint256) -#define function previewWithdraw(uint256 assets) view returns (uint256) -#define function previewRedeem(uint256 shares) view returns (uint256) - -#define function maxDeposit(address) view returns (uint256) -#define function maxMint(address) view returns (uint256) -#define function maxWithdraw(address owner) view returns (uint256) -#define function maxRedeem(address owner) view returns (uint256) - -// Immutables offsets -#define constant ASSET_OFFSET = 0x0000000000000000000000000000000000000000000000000000000000000100 - -#define constant TYPE_UINT_256_MAX = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff - -/// @notice Constructor -#define macro ERC4626_CONSTRUCTOR() = takes (0) returns (0) { - // Copy the asset address into memory and then the stack from the bytecode - 0x20 // [size] - byte size to copy - 0x20 [ASSET_OFFSET] sub // [asset_offset_now, size] - codesize sub // [offset, size] - offset in the code to copy from - 0x00 // [mem, offset, size] - offset in memory to copy to - codecopy // [] - stores asset at 0x00 - - // Store the decimals function selector in memory to call - __FUNC_SIG(decimals) // [sig_right_padded] - 0xE0 shl // [sig_left_padded] - 0x20 mstore // [] - - // Call the asset to get its decimals - 0x20 // [retSize] - 0x00 // [retOffset, retSize] - 0x04 // [argSize, retOffset, retSize] - 0x20 // [argOffset, argSize, retOffset, retSize] - 0x00 mload // [to, argOffset, argSize, retOffset, retSize] - gas // [gas, to, argOffset, argSize, retOffset, retSize] - staticcall // [success] - - // If the call failed, revert - cont jumpi // [] - 0x00 dup1 revert // [] - cont: - - // Load the decimals - 0x00 mload // [decimals] - - // Configure the initial domain separator - chainid [INITIAL_CHAIN_ID] sstore // [decimals] - COMPUTE_DOMAIN_SEPARATOR() // [DOMAIN_SEPARATOR, decimals] - [INITIAL_DOMAIN_SEPARATOR] sstore // [decimals] - - // Copy the runtime bytecode with constructor argument concatenated. - __codesize(CONSTRUCTOR) // [offset, decimals] - dup1 // [offset, offset, decimals] - codesize // [total_size, offset, offset, decimals] - sub // [runtime_size, offset, decimals] - dup1 // [runtime_size, runtime_size, offset, decimals] - swap2 // [offset, runtime_size, runtime_size, decimals] - returndatasize // [return_offset, offset, runtime_size, runtime_size, decimals] - codecopy // [runtime_size, decimals] - - // Add the decimals at the of the bytecode. - swap1 // [decimals, runtime_size] - dup2 // [runtime_size, decimals, runtime_size] - returndatasize add mstore // [runtime_size] - - // Return the runtime bytecode. - 0x20 add // [new_runtime_size] - returndatasize // [return_offset, new_runtime_size] - return // [] -} - -/// @notice Returns the ERC4626 decimals -#define macro ERC4626_DECIMALS() = takes (0) returns (0) { - _GET_IMMUTABLE(DECIMALS_OFFSET, 0x00) // [decimals] - 0x00 mstore // [] - 0x20 0x00 return // [] -} - -/// @notice Returns the ERC4626 asset -#define macro ERC4626_ASSET() = takes (0) returns (0) { - _GET_IMMUTABLE(ASSET_OFFSET, 0x00) // [asset] - 0x00 mstore // [] - 0x20 0x00 return // [] -} - -// ------------------------------------------------------ -// DEPOSIT/WITHDRAWAL LOGIC -// ------------------------------------------------------ - -/// @notice Mint -/// @notice Mints a {receiver} x amount of {assets} proportional to the input {shares} -/// @param {shares} [uint256] The amount of shares to mint -#define macro ERC4626_MINT() = takes (0) returns (0) { - 0x24 calldataload // [receiver] - 0x04 calldataload // [shares, receiver] - MINT_INNER() // [assets] - 0x00 mstore // [] - 0x20 0x00 return // [] -} - -/// @notice Mint Internal Helper -#define macro MINT_INNER() = takes (2) returns (1) { - // Input stack: [shares, receiver] - // Output stack: [assets] - - // Preview the mint given the number of shares - dup1 // [shares, shares, receiver] - PREVIEW_MINT_INNER() // [assets, shares, receiver] - - // Transfer the assets from the caller to the vault - - // Store the transferFrom selector in memory - __FUNC_SIG(transferFrom) // [selector, assets, shares, receiver] - 0xE0 shl // [selector, assets, shares, receiver] - 0x00 mstore // [assets, shares, receiver] - - // Store the caller in memory as the first arg - caller 0x04 mstore // [assets, shares, receiver] - - // Store this address as the second call argument in memory - address 0x24 mstore // [assets, shares, receiver] - - // Store assets as the third call argument in memory - dup1 0x44 mstore // [assets, shares, receiver] - - // Load the asset as the call destination - _GET_IMMUTABLE(ASSET_OFFSET, 0x80) // [asset, assets, shares, receiver] - - // Construct the call - 0x00 // [retSize, asset, assets, shares, receiver] - 0x00 // [retOffset, retSize, asset, assets, shares, receiver] - 0x64 // [argSize, retOffset, retSize, asset, assets, shares, receiver] - 0x00 // [argOffset, argSize, retOffset, retSize, asset, assets, shares, receiver] - 0x00 // [value, argOffset, argSize, retOffset, retSize, asset, assets, shares, receiver] - dup6 // [to, value, argOffset, argSize, retOffset, retSize, asset, assets, shares, receiver] - gas // [gas, to, value, argOffset, argSize, retOffset, retSize, asset, assets, shares, receiver] - call // [success, asset, assets, shares, receiver] - - // Verify the call succeeded - success jumpi // [asset, assets, shares, receiver] - 0x00 dup1 revert // [] - success: - - // Mint vault shares to the receiver - pop // [assets, shares, receiver] - dup3 dup3 // [shares, receiver, assets, shares, receiver] - _MINT() // [assets, shares, receiver] - - // Emit the deposit event - dup1 0x00 mstore // [assets, shares, receiver] - dup2 0x20 mstore // [assets, shares, receiver] - dup3 caller // [msg.sender, receiver, assets, shares, receiver] - __EVENT_HASH(Deposit) // [event_hash, msg.sender, receiver, assets, shares, receiver] - 0x40 0x00 log3 // [assets, shares, receiver] - - // Call the after deposit hook - swap1 dup2 // [assets, shares, assets, receiver] - AFTER_DEPOSIT() // [assets, receiver] - - // Return just the assets - swap1 pop // [assets] -} - -/// @notice Redeem -/// @notice Redeems a {receiver} x amount of {assets} proportional to the input {shares} -/// @param {shares} [uint256] The amount of shares to redeem -/// @param {receiver} [address] The address to receive the assets -/// @param {owner} [address] The address that owns the shares -#define macro ERC4626_REDEEM() = takes (0) returns (0) { - 0x44 calldataload // [owner] - 0x24 calldataload // [receiver, owner] - 0x04 calldataload // [shares, receiver, owner] - REDEEM_INNER() // [assets] - 0x00 mstore // [] - 0x20 0x00 return // [] -} - -/// @notice Redeem Internal Helper -#define macro REDEEM_INNER() = takes (3) returns (1) { - // Input stack: [shares, receiver, owner] - // Output stack: [assets] - - // Jump ahead if msg.sender == owner - dup3 caller eq ahead jumpi // [shares, receiver, owner] - - // Check if the caller is approved to redeem the shares - - // Get the allowance[owner][msg.sender] - caller dup4 // [owner, msg.sender, shares, receiver, owner] - [APPROVAL_SLOT] // [slot, owner, msg.sender, shares, receiver, owner] - LOAD_ELEMENT_FROM_KEYS_2D(0x00) // [allowance, shares, receiver, owner] - - // If the allowed is no infinite approval, set to the allowance less shares - dup1 [TYPE_UINT_256_MAX] // [type(uint256).max, allowance, allowance, shares, receiver, owner] - eq infinite jumpi // [allowance, shares, receiver, owner] - - // Set the new allowance - dup2 dup2 sub // [new_allowance, allowance, shares, receiver, owner] - caller dup6 [APPROVAL_SLOT] // [slot, owner, msg.sender, new_allowance, allowance, shares, receiver, owner] - STORE_ELEMENT_FROM_KEYS_2D(0x00) // [allowance, shares, receiver, owner] - - // Jump dests for initial checks - infinite: - pop // [shares, receiver, owner] - ahead: - - // Validate that the assets are non-zero - dup1 CONVERT_TO_ASSETS_INNER() // [assets, shares, receiver, owner] - dup1 non_zero jumpi // [assets, shares, receiver, owner] - ZERO_ASSETS(0x00) - non_zero: - - // Call the before withdraw hook - dup2 dup2 BEFORE_WITHDRAW() // [assets, shares, receiver, owner] - - // Burn the shares, input stack: [shares, owner] - dup4 dup3 _BURN() // [assets, shares, receiver, owner] - - // Emit the withdraw event - dup1 0x00 mstore // [assets, shares, receiver, owner] - dup2 0x20 mstore // [assets, shares, receiver, owner] - dup4 dup4 caller // [msg.sender, receiver, owner, assets, shares, receiver, owner] - __EVENT_HASH(Withdraw) // [event_hash, msg.sender, receiver, owner, assets, shares, receiver, owner] - 0x40 0x00 log4 // [assets, shares, receiver, owner] - - // Transfer the assets from the receiver to the vault - // Store the transfer selector in memory - __FUNC_SIG(transfer) // [selector, assets, shares, receiver, owner] - 0xE0 shl // [selector, assets, shares, receiver, owner] - 0x00 mstore // [assets, shares, receiver, owner] - - // Store the receiver in memory as the first arg - dup3 0x04 mstore // [assets, shares, receiver, owner] - - // Store the assets as the second call argument in memory - dup1 0x24 mstore // [assets, shares, receiver, owner] - - // Load the asset as the call destination - _GET_IMMUTABLE(ASSET_OFFSET, 0x80) // [asset, assets, shares, receiver, owner] - // [ADDRESS] - - // Construct the call - 0x00 // [retSize, asset, assets, shares, receiver, owner] - 0x00 // [retOffset, retSize, asset, assets, shares, receiver, owner] - 0x44 // [argSize, retOffset, retSize, asset, assets, shares, receiver, owner] - 0x00 // [argOffset, argSize, retOffset, retSize, asset, assets, shares, receiver, owner] - 0x00 // [value, argOffset, argSize, retOffset, retSize, asset, assets, shares, receiver, owner] - dup6 // [to, value, argOffset, argSize, retOffset, retSize, asset, assets, shares, receiver, owner] - gas // [gas, to, value, argOffset, argSize, retOffset, retSize, asset, assets, shares, receiver, owner] - call // [success, asset, assets, shares, receiver, owner] - - // Verify the call succeeded - success jumpi // [asset, assets, shares, receiver, owner] - 0x00 dup1 revert // [] - success: - - // Clean the stack and return the assets - pop swap4 pop pop pop // [assets] -} - -/// @notice Deposit -/// @notice Deposits the asset in exchange for shares -/// @param {assets} [uint256] The amount of assets to deposit -/// @param {receiver} [address] The address to receive the shares -#define macro ERC4626_DEPOSIT() = takes (0) returns (0) { - 0x24 calldataload // [receiver] - 0x04 calldataload // [assets, receiver] - DEPOSIT_INNER() // [shares] - 0x00 mstore // [] - 0x20 0x00 return // [] -} - -/// @notice Deposit assets into the ERC4626 Vault -#define macro DEPOSIT_INNER() = takes (2) returns (1) { - // Input stack: [assets, receiver] - // Output stack: [shares] - - // Validate that the assets shares are not zero - dup1 // [assets, assets, receiver] - PREVIEW_DEPOSIT_INNER() // [shares, assets, receiver] - dup1 cont jumpi // [shares, assets, receiver] - ZERO_SHARES(0x00) - cont: - - // Store the transferFrom selector in memory - __FUNC_SIG(transferFrom) // [selector, shares, assets, receiver] - 0xE0 shl // [selector, shares, assets, receiver] - 0x00 mstore // [shares, assets, receiver] - - // Store the caller in memory as the first arg - caller 0x04 mstore // [shares, assets, receiver] - - // Store this address as the second call argument in memory - address 0x24 mstore // [shares, assets, receiver] - - // Store assets as the third call argument in memory - dup2 0x44 mstore // [shares, assets, receiver] - - // Load the asset - _GET_IMMUTABLE(ASSET_OFFSET, 0x80) // [asset, shares, assets, receiver] - - // Construct the call - 0x00 // [retSize, asset, shares, assets, receiver] - 0x00 // [retOffset, retSize, asset, shares, assets, receiver] - 0x64 // [argSize, retOffset, retSize, asset, shares, assets, receiver] - 0x00 // [argOffset, argSize, retOffset, retSize, asset, shares, assets, receiver] - 0x00 // [value, argOffset, argSize, retOffset, retSize, asset, shares, assets, receiver] - dup6 // [to, value, argOffset, argSize, retOffset, retSize, asset, shares, assets, receiver] - gas // [gas, to, value, argOffset, argSize, retOffset, retSize, asset, shares, assets, receiver] - call // [success, asset, shares, assets, receiver] - - // Verify the call succeeded - success jumpi // [asset, shares, assets, receiver] - 0x00 dup1 revert // [] - success: - - // Mint to the receiver - pop dup3 dup2 // [shares, receiver, shares, assets, receiver] - - _MINT() // [shares, assets, receiver] - - // Emit the Deposit Event - dup2 0x00 mstore // [shares, assets, receiver] - dup1 0x20 mstore // [shares, assets, receiver] - dup3 caller // [msg.sender, receiver, shares, assets, receiver] - __EVENT_HASH(Deposit) // [event_hash, msg.sender, receiver, shares, assets, receiver] - 0x40 0x00 log3 // [shares, assets, receiver] - - // Call the after deposit hook - dup1 swap2 swap1 // [shares, assets, shares, receiver] - AFTER_DEPOSIT() // [shares, receiver] - - // Return the shares - swap1 pop // [shares] -} - -/// @notice Withdraw -/// @notice Withdraws the shares in exchange for the underlying assets -/// @param {assets} [uint256] The amount of shares to withdraw -/// @param {receiver} [address] The address to receive the assets -/// @param {owner} [address] The address that owns the shares -#define macro ERC4626_WITHDRAW() = takes (0) returns (0) { - 0x44 calldataload // [owner] - 0x24 calldataload // [receiver, owner] - 0x04 calldataload // [assets, receiver, owner] - WITHDRAWAL_INNER() // [shares] - 0x00 mstore // [] - 0x20 0x00 return // [] -} - -/// @notice Withdraws assets from an ERC4626 Vault -#define macro WITHDRAWAL_INNER() = takes (3) returns (1) { - // Input stack: [assets, receiver, owner] - // Output stack: [shares] - - // Get the shares from the assets - dup1 PREVIEW_WITHDRAW_INNER() // [shares, assets, receiver, owner] - - // Skip ahead if msg.sender is the owner - dup4 caller eq owner_jump jumpi // [shares, assets, receiver, owner] - - // Get the allowance[owner][msg.sender] - caller dup5 // [owner, msg.sender, shares, assets, receiver, owner] - [APPROVAL_SLOT] // [slot, owner, msg.sender, shares, assets, receiver, owner] - LOAD_ELEMENT_FROM_KEYS_2D(0x00) // [allowance, shares, assets, receiver, owner] - - // If the allowed is no infinite approval, set to the allowance less shares - dup1 [TYPE_UINT_256_MAX] // [type(uint256).max, allowance, allowance, shares, assets, receiver, owner] - eq infinite jumpi // [allowance, shares, assets, receiver, owner] - - // Set the new allowance - dup2 dup2 sub // [new_allowance, allowance, shares, assets, receiver, owner] - caller dup6 [APPROVAL_SLOT] // [slot, owner, msg.sender, new_allowance, allowance, shares, assets, receiver, owner] - STORE_ELEMENT_FROM_KEYS_2D(0x00) // [allowance, shares, assets, receiver, owner] - - infinite: - pop // [shares, assets, receiver, owner] - - owner_jump: - - // Call the before withdrawal hook - dup1 dup3 // [assets, shares, shares, assets, receiver, owner] - BEFORE_WITHDRAW() // [shares, assets, receiver, owner] - - // Burn the shares - dup4 dup2 // [shares, owner, shares, assets, receiver, owner] - _BURN() // [shares, assets, receiver, owner] - - // Emit the Withdraw Event - dup2 0x00 mstore // [shares, assets, receiver, owner] - dup1 0x20 mstore // [shares, assets, receiver, owner] - dup4 dup3 caller // [msg.sender, assets, owner, shares, assets, receiver, owner] - __EVENT_HASH(Withdraw) // [event_hash, msg.sender, assets, owner, shares, assets, receiver, owner] - 0x40 0x00 log4 // [shares, assets, receiver, owner] - - // Store the transfer selector in memory - __FUNC_SIG(transfer) // [selector, shares, assets, receiver, owner] - 0xE0 shl // [selector, shares, assets, receiver, owner] - 0x00 mstore // [shares, assets, receiver, owner] - - // Store the receiver in memory as the first arg - dup3 0x04 mstore // [shares, assets, receiver, owner] - - // Store this address as the second call argument in memory - dup2 0x24 mstore // [shares, assets, receiver, owner] - - // Load asset from storage - _GET_IMMUTABLE(ASSET_OFFSET, 0x80) // [asset, shares, assets, receiver, owner] - - // Construct the call - 0x00 // [retSize, asset, shares, assets, receiver, owner] - 0x00 // [retOffset, retSize, asset, shares, assets, receiver, owner] - 0x44 // [argSize, retOffset, retSize, asset, shares, assets, receiver, owner] - 0x00 // [argOffset, argSize, retOffset, retSize, asset, shares, assets, receiver, owner] - 0x00 // [value, argOffset, argSize, retOffset, retSize, asset, shares, assets, receiver, owner] - dup6 // [to, value, argOffset, argSize, retOffset, retSize, asset, shares, assets, receiver, owner] - gas // [gas, to, value, argOffset, argSize, retOffset, retSize, asset, shares, assets, receiver, owner] - call // [success, asset, shares, assets, receiver, owner] - - // Verify the call succeeded - success jumpi // [asset, shares, assets, receiver, owner] - 0x00 dup1 revert // [] - success: - - // Return shares - pop // [shares, assets, receiver, owner] - swap3 pop pop pop // [shares] -} - - -// ------------------------------------------------------ -// ACCOUNTING LOGIC -// ------------------------------------------------------ - -// Input Stack: [] -// Output Stack: [total_assets] -/// @notice Returns the total amount of assets in the Vault -/// @notice REQUIRES OVERRIDEN IMPLEMENTATION -// #define macro TOTAL_ASSETS_INNER() = takes (0) returns (1) - -/// @notice Returns the total amount of assets in the Vault -#define macro TOTAL_ASSETS() = takes (0) returns (0) { - TOTAL_ASSETS_INNER() // [total_assets] - 0x00 mstore // [] - 0x20 0x00 return // [] -} - -/// @notice Returns the amount of assets needed to mint the given amount of shares -/// @param {shares} [uint256] The amount of shares to mint -#define macro PREVIEW_MINT() = takes (0) returns (0) { - 0x04 calldataload // [shares] - PREVIEW_MINT_INNER() // [assets] - 0x00 mstore // [] - 0x20 0x00 return // [] -} - -#define macro PREVIEW_MINT_INNER() = takes (1) returns (1) { - // Input Stack: [shares] - // Output Stack: [assets] - - // Load the total supply - [TOTAL_SUPPLY_SLOT] sload // [supply, shares] - - // Return shares if supply is zero - dup1 calculate jumpi // [supply, shares] - pop cont jump // [] - - // Otherwise mul div up - calculate: - - swap1 // [shares, supply] - TOTAL_ASSETS_INNER() swap1 // [shares, total_assets, supply] - MUL_DIV_UP(fail) // [shares] - cont jump - - // Fail with an arithmetic overflow - fail: - [ARITHMETIC_OVERFLOW] PANIC() - - // Resume withdrawal with share count - cont: // [assets] -} - -/// @notice Calculates the amount of shares that would be exchanged for a given amount of assets -/// @param {assets} [uint256] The amount of assets to exchange -#define macro PREVIEW_DEPOSIT() = takes (1) returns (1) { - 0x04 calldataload // [assets] - PREVIEW_DEPOSIT_INNER() // [shares] - 0x00 mstore // [] - 0x20 0x00 return // [] -} - -#define macro PREVIEW_DEPOSIT_INNER() = takes (1) returns (1) { - CONVERT_TO_SHARES_INNER() // [shares] -} - -/// @notice Converts assets to shares -/// @param {assets} [uint256] The amount of assets to convert -#define macro CONVERT_TO_SHARES() = takes (0) returns (0) { - 0x04 calldataload // [assets] - CONVERT_TO_SHARES_INNER() // [shares] - 0x00 mstore // [] - 0x20 0x00 return // [] -} - -#define macro CONVERT_TO_SHARES_INNER() = takes (1) returns (1) { - // Input Stack: [assets] - // Output Stack: [shares] - - [TOTAL_SUPPLY_SLOT] sload // [supply, assets] - - // Return assets if supply is zero - dup1 calculate jumpi // [supply, assets] - pop cont jump // [] - - // Otherwise mul div down - calculate: - - TOTAL_ASSETS_INNER() swap2 // [assets, supply, total_assets] - MUL_DIV_DOWN(fail) // [shares] - cont jump - - // Fail with an arithmetic overflow - fail: - [ARITHMETIC_OVERFLOW] PANIC() - - // Resume withdrawal with share count - cont: // [shares] -} - -/// @notice Converts shares to assets -/// @param {shares} [uint256] The amount of shares to convert -#define macro CONVERT_TO_ASSETS() = takes (0) returns (0) { - 0x04 calldataload // [shares] - CONVERT_TO_ASSETS_INNER() // [assets] - 0x00 mstore // [] - 0x20 0x00 return // [] -} - -#define macro CONVERT_TO_ASSETS_INNER() = takes (1) returns (1) { - // Input Stack: [shares] - // Output Stack: [assets] - - [TOTAL_SUPPLY_SLOT] sload // [supply, shares] - - // Return assets if supply is zero - dup1 calculate jumpi // [supply, shares] - pop cont jump // [] - - // Otherwise mul div down - calculate: - - swap1 // [shares, supply] - TOTAL_ASSETS_INNER() swap1 // [shares, total_assets, supply] - MUL_DIV_DOWN(fail) // [assets] - cont jump - - // Fail with an arithmetic overflow - fail: - [ARITHMETIC_OVERFLOW] PANIC() - - // Resume withdrawal with share count - cont: // [assets] -} - -/// @notice Calculates the amount of shares that would be exchanged for a given amount of assets -/// @param {assets} [uint256] The amount of assets to exchange -#define macro PREVIEW_WITHDRAW() = takes (1) returns (1) { - 0x04 calldataload // [assets] - PREVIEW_WITHDRAW_INNER() // [shares] - 0x00 mstore // [] - 0x20 0x00 return // [] -} - -#define macro PREVIEW_WITHDRAW_INNER() = takes (1) returns (1) { - // Input Stack: [assets] - // Output Stack: [shares] - - [TOTAL_SUPPLY_SLOT] sload // [supply, assets] - - // Return assets if supply is zero - dup1 calculate jumpi // [supply, assets] - pop dont_fail jump // [] - - // Otherwise mul div up - calculate: - - TOTAL_ASSETS_INNER() swap2 // [assets, supply, total_assets] - MUL_DIV_UP(fail) // [shares] - dont_fail jump - - // Fail with an arithmetic overflow - fail: - [ARITHMETIC_OVERFLOW] PANIC() - - // Resume withdrawal with share count - dont_fail: // [shares] -} - -/// @notice Calculates the amount of assets that would be exchanged for a given amount of shares on redemption -/// @param {shares} [uint256] The amount of shares to exchange -#define macro PREVIEW_REDEEM() = takes (0) returns (0) { - 0x04 calldataload // [shares] - CONVERT_TO_ASSETS_INNER() // [assets] - 0x00 mstore // [] - 0x20 0x00 return // [] -} - -// ------------------------------------------------------ -// DEPOSIT/WITHDRAWAL LIMIT LOGIC -// ------------------------------------------------------ - -/// @notice Max Deposit -/// @notice Returns the maximum amount of assets available to deposit -#define macro MAX_DEPOSIT() = takes (0) returns (0) { - [TYPE_UINT_256_MAX] // [type(uint256).max] - 0x00 mstore // [] - 0x20 0x00 return // [] -} - -/// @notice Max Mint -/// @notice Returns the maximum amount of shares available to mint -#define macro MAX_MINT() = takes (0) returns (0) { - [TYPE_UINT_256_MAX] // [type(uint256).max] - 0x00 mstore // [] - 0x20 0x00 return // [] -} - -/// @notice Max Withdraw -/// @notice Returns the maximum amount of assets available to withdraw -/// @param {owner} [address] The address of the account to withdraw assets from -#define macro MAX_WITHDRAW() = takes (0) returns (0) { - 0x04 calldataload // [owner] - [BALANCE_SLOT] sload // [balanceOf[owner]] - CONVERT_TO_ASSETS_INNER() // [assets] - 0x00 mstore // [] - 0x20 0x00 return // [] -} - -/// @notice Max Redeem -/// @notice Returns the maximum amount of shares available to redeem -/// @param {owner} [address] The address of the account to redeem shares from -#define macro MAX_REDEEM() = takes (0) returns (0) { - 0x04 calldataload // [owner] - [BALANCE_SLOT] sload // [balanceOf[owner]] - 0x00 mstore // [] - 0x20 0x00 return // [] -} - -// ------------------------------------------------------ -// INTERNAL HOOKS LOGIC -// ------------------------------------------------------ - -// Input Stack: [assets, shares] -// Output Stack: [] -/// @notice Called before a withdrawal -/// @notice REQUIRES OVERRIDEN IMPLEMENTATION -// #define macro BEFORE_WITHDRAW() = takes (2) returns (0) - -// Input Stack: [assets, shares] -// Output Stack: [] -/// @notice Called after a deposit -/// @notice REQUIRES OVERRIDEN IMPLEMENTATION -// #define macro AFTER_DEPOSIT() = takes (2) returns (0) - -// ------------------------------------------------------ -// DISPATCH LOGIC -// ------------------------------------------------------ - -/// @notice An internal function dispatcher -#define macro ERC4626_MAIN() = takes (1) returns (1) { - // Input stack: [func_selector] - // Output stack: [func_selector] - - dup1 __FUNC_SIG(decimals) eq decimals_jump jumpi // [func_selector] - dup1 __FUNC_SIG(asset) eq asset_jump jumpi // [func_selector] - - dup1 __FUNC_SIG(deposit) eq deposit_jump jumpi // [func_selector] - dup1 __FUNC_SIG(withdraw) eq withdraw_jump jumpi // [func_selector] - dup1 __FUNC_SIG(mint) eq mint_jump jumpi // [func_selector] - dup1 __FUNC_SIG(redeem) eq redeem_jump jumpi // [func_selector] - - dup1 __FUNC_SIG(totalAssets) eq total_assets_jump jumpi // [func_selector] - dup1 __FUNC_SIG(convertToShares) eq convert_to_shares_jump jumpi // [func_selector] - dup1 __FUNC_SIG(convertToAssets) eq convert_to_assets_jump jumpi // [func_selector] - dup1 __FUNC_SIG(previewDeposit) eq preview_deposit_jump jumpi // [func_selector] - dup1 __FUNC_SIG(previewMint) eq preview_mint_jump jumpi // [func_selector] - dup1 __FUNC_SIG(previewWithdraw) eq preview_withdraw_jump jumpi // [func_selector] - dup1 __FUNC_SIG(previewRedeem) eq preview_redeem_jump jumpi // [func_selector] - - dup1 __FUNC_SIG(maxDeposit) eq max_deposit_jump jumpi // [func_selector] - dup1 __FUNC_SIG(maxMint) eq max_mint_jump jumpi // [func_selector] - dup1 __FUNC_SIG(maxWithdraw) eq max_withdraw_jump jumpi // [func_selector] - dup1 __FUNC_SIG(maxRedeem) eq max_redeem_jump jumpi // [func_selector] - - ERC20_MAIN() // [func_selector] - - // Bubble up to the parent macro - no_match jump - - decimals_jump: - ERC4626_DECIMALS() - asset_jump: - ERC4626_ASSET() - - deposit_jump: - ERC4626_DEPOSIT() - withdraw_jump: - ERC4626_WITHDRAW() - mint_jump: - ERC4626_MINT() - redeem_jump: - ERC4626_REDEEM() - - total_assets_jump: - TOTAL_ASSETS() - convert_to_shares_jump: - CONVERT_TO_SHARES() - convert_to_assets_jump: - CONVERT_TO_ASSETS() - preview_deposit_jump: - PREVIEW_DEPOSIT() - preview_mint_jump: - PREVIEW_MINT() - preview_withdraw_jump: - PREVIEW_WITHDRAW() - preview_redeem_jump: - PREVIEW_REDEEM() - - max_deposit_jump: - MAX_DEPOSIT() - max_mint_jump: - MAX_MINT() - max_withdraw_jump: - MAX_WITHDRAW() - max_redeem_jump: - MAX_REDEEM() - - // Resume parent dispatching - no_match: // [func_selector] -} diff --git a/src/tokens/interfaces/IERC20.sol b/src/tokens/interfaces/IERC20.sol index 08e2ac86..8e4a26c6 100644 --- a/src/tokens/interfaces/IERC20.sol +++ b/src/tokens/interfaces/IERC20.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; +pragma solidity ^0.8.15; interface TSOwnable { function owner() external returns (address); diff --git a/src/utils/__TEMP__ahkbbusaspkdjqohbmhkbfmghcmmpksnCREATE3.huff b/src/utils/__TEMP__ahkbbusaspkdjqohbmhkbfmghcmmpksnCREATE3.huff deleted file mode 100644 index 48b6ccf8..00000000 --- a/src/utils/__TEMP__ahkbbusaspkdjqohbmhkbfmghcmmpksnCREATE3.huff +++ /dev/null @@ -1,177 +0,0 @@ -#define function deploy(bytes32, bytes, uint256) payable returns (address) -#define function getDeployed(bytes32) view returns (address) - -#define macro CREATE_3_DEPLOY_WRAPPER() = takes (0) returns (0) { - 0x44 calldataload // [value] - 0x24 calldataload // [&creationCode, value] - 0x04 calldataload // [salt, &creationCode, value] - CREATE_3_DEPLOY() // [deployed] - 0x00 mstore // [] - 0x20 0x00 return // [] -} - -#define macro CREATE_3_GET_DEPLOYED_WRAPPER() = takes (0) returns (0) { - 0x04 calldataload // [salt] - CREATE_3_GET_DEPLOYED() // [deployed] - 0x00 mstore // [] - 0x20 0x00 return // [] -} - -#define macro MAIN() = { - pc calldataload 0xe0 shr - - dup1 __FUNC_SIG(deploy) eq deploy_jump jumpi - dup1 __FUNC_SIG(getDeployed) eq get_deployed_jump jumpi - - // Exit if selector does not match - 0x00 dup1 revert - - deploy_jump: - CREATE_3_DEPLOY_WRAPPER() - get_deployed_jump: - CREATE_3_GET_DEPLOYED_WRAPPER() -} - -/// @title Create3 -/// @notice SPDX-License-Identifier: MIT -/// @author Maddiaa -/// @author asnared -/// @notice Deploy to deterministic addresses without an initcode factor -/// @notice Adapted from Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/CREATE3.sol) - -#include "./CommonErrors.huff" - - -// Proxy Constants -#define constant PROXY_BYTECODE = 0x67363d3d37363d34f03d5260086018f3 -#define constant PROXY_BYTECODE_HASH = 0x21c35dbe1b344a2488cf3321d6ce542f8e9f305544ff09e4993a62319a497c1f - -//--------------------------------------------------------------------------------// -// Opcode | Opcode + Arguments | Description | Stack View // -//--------------------------------------------------------------------------------// -// 0x36 | 0x36 | CALLDATASIZE | size // -// 0x3d | 0x3d | RETURNDATASIZE | 0 size // -// 0x3d | 0x3d | RETURNDATASIZE | 0 0 size // -// 0x37 | 0x37 | CALLDATACOPY | // -// 0x36 | 0x36 | CALLDATASIZE | size // -// 0x3d | 0x3d | RETURNDATASIZE | 0 size // -// 0x34 | 0x34 | CALLVALUE | value 0 size // -// 0xf0 | 0xf0 | CREATE | newContract // -//--------------------------------------------------------------------------------// -// Opcode | Opcode + Arguments | Description | Stack View // -//--------------------------------------------------------------------------------// -// 0x67 | 0x67XXXXXXXXXXXXXXXX | PUSH8 bytecode | bytecode // -// 0x3d | 0x3d | RETURNDATASIZE | 0 bytecode // -// 0x52 | 0x52 | MSTORE | // -// 0x60 | 0x6008 | PUSH1 08 | 8 // -// 0x60 | 0x6018 | PUSH1 18 | 24 8 // -// 0xf3 | 0xf3 | RETURN | // -//--------------------------------------------------------------------------------// - -/// @notice Deploy a new contract with our pre-made bytecode via CREATE2 -#define macro CREATE_3_DEPLOY() = takes (3) returns (1) { - // Input Stack: [salt, &creationCode, value] - // Output Stack: [deployed] - - // Create the proxy - dup1 0x10 // [size, salt, salt, &creationCode, value] - - // Shift the proxy bytecode left - [PROXY_BYTECODE] // [bytecode, size, salt, salt, &creationCode, value, bytecode] - 0x80 shl // [RIGHTPAD(bytecode), size, salt, salt, &creationCode, value, bytecode] - 0x00 mstore // [size, salt, salt, &creationCode, value] - 0x00 // [offset, size, salt, salt, &creationCode, value] - 0x00 // [value, offset, size, salt, salt, &creationCode, value] - create2 // [address, salt, &creationCode, value] - - // Check the address of of the proxy is not null - dup1 iszero // [address == 0, address, salt, &creationCode, value] - deployment_failed jumpi // [address, salt, &creationCode, value] - - // Load the length of the creation code - dup3 0x04 add calldataload // [creationCode.length, address, salt, &creationCode, value] - - // Copy the code from calldata to memory at memory position 0x20 - dup1 0x05 shl // [size, creationCode.length, address, salt, &creationCode, value] - dup5 0x24 add // [calldataOffset, size, creationCode.length, address, salt, &creationCode, value] - 0x20 // [destOffset, calldataOffset, size, creationCode.length, address, salt, &creationCode, value] - calldatacopy // [creationCode.length, address, salt, &creationCode, value] - - // Call the proxy with the creation code - 0x20 // [retSize, creationCode.length, address, salt, &creationCode, value] - 0x00 // [retOffset, retSize, creationCode.length, address, salt, &creationCode, value] - dup3 // [argSize, retOffset, retSize, creationCode.length, address, salt, &creationCode, value] - 0x20 // [argOffset, argSize, retOffset, retSize, creationCode.length, address, salt, &creationCode, value] - dup9 // [value, argOffset, argSize, retOffset, retSize, creationCode.length, address, salt, &creationCode, value] - dup7 // [to, value, argOffset, argSize, retOffset, retSize, creationCode.length, address, salt, &creationCode, value] - gas // [gas, to, value, argOffset, argSize, retOffset, retSize, creationCode.length, address, salt, &creationCode, value] - call // [success, creationCode.length, address, salt, &creationCode, value] - iszero // [success == 0, creationCode.length, address, salt, &creationCode, value] - init_failed jumpi // [creationCode.length, address, salt, &creationCode, value] - - // Get the deployed contract using the salt and make sure it has code at the address - dup3 CREATE_3_GET_DEPLOYED() // [deployed, creationCode.length, address, salt, &creationCode, value] - dup1 extcodesize // [deployed == 0, deployed, creationCode.length, address, salt, &creationCode, value] - iszero init_failed jumpi // [deployed, creationCode.length, address, salt, &creationCode, value] - - // Clean up stack and return - swap5 pop pop pop pop pop // [deployed] - done jump - - deployment_failed: - DEPLOYMENT_FAILED(0x00) - init_failed: - INITIALIZATION_FAILED(0x00) - - done: -} - -#define macro CREATE_3_GET_DEPLOYED() = takes (1) returns (1) { - // Input Stack : [salt] - // Output Stack: [deployed_address] - - // Store 0xff | (right_padded_address >> 1) in memory - __RIGHTPAD(0xff) // [rightpad(0xff), salt] - address 0x58 shl // [rightpad(address), rightpad(0xff), salt] - or // [[0xff][address], salt] - 0x00 mstore // [salt] - - // Store the salt in memory at position 0x15 - 0x15 mstore // [] - - // Store the hash in memory at 0x35 - [PROXY_BYTECODE_HASH] // [hash] - 0x35 mstore // [] - - // Hash the memory from 0x00:0x55 - 0x55 0x00 sha3 // [keccak] - - // ---------------------------------------- // - // Memory Layout // - // ---------------------------------------- // - // prefix | address | nonce | empty // - // 0xd694 | | 01 | 000..000 // - // ---------------------------------------- // - - // 0xd6 = 0xc0 (short RLP prefix) + 0x16 (length of: 0x94 ++ proxy ++ 0x01) - // 0x94 = 0x80 + 0x14 (0x14 = the length of an address, 20 bytes, in hex) - - // Clear the top 10 bytes of the hash - 0x60 shl 0x10 shr // [proxy_address] - - // return rpl encoded - __RIGHTPAD(0xd694) // [0xd694, proxy_address] - or // [ [0xd694][proxy_address] ] - - // Append a 0x01 to the end of the address - - 0x01 0x48 shl // [0x01 << 9, [0xd694][proxy_address]] - or // [ [0xd694][proxy_address][01] ] - - // Hash the packed encoding in memory position 0x00 - 0x00 mstore // [] - 0x17 0x00 sha3 // [hash] - - // Clear the top 12 bytes using shifts - 0x60 shl 0x60 shr // [proxy_address] -} diff --git a/src/utils/__TEMP__ajvxrvsbqwgufgegzhdrxxamgnvfwtnzJumpTableUtil.huff b/src/utils/__TEMP__ajvxrvsbqwgufgegzhdrxxamgnvfwtnzJumpTableUtil.huff deleted file mode 100644 index b42ce920..00000000 --- a/src/utils/__TEMP__ajvxrvsbqwgufgegzhdrxxamgnvfwtnzJumpTableUtil.huff +++ /dev/null @@ -1,149 +0,0 @@ -#define function getJumpdestMem(uint256) view returns (uint256) -#define function getJumpdestStack(uint256) view returns (uint256) -#define function getJumpdestMemPacked(uint256) view returns (uint256) -#define function getJumpdestStackPacked(uint256) view returns (uint256) - -#define jumptable TEST_TABLE { - test_label_a test_label_b test_label_c test_label_d -} - -#define jumptable__packed TEST_TABLE_PACKED { - test_label_a test_label_b test_label_c test_label_d -} - -#define macro GET_JUMPDEST_MEM_WRAPPER() = takes (0) returns (0) { - __tablestart(TEST_TABLE) // [table_start] - 0x04 calldataload // [n, table_start] - - // Load a jumpdest inside of `TEST_TABLE` at index `n` into - // memory at 0x00. - LOAD_FROM_JT(0x00) // [] - 0x20 0x00 return -} - -#define macro GET_JUMPDEST_STACK_WRAPPER() = takes (0) returns (0) { - __tablestart(TEST_TABLE) // [table_start] - 0x04 calldataload // [n, table_start] - RETRIEVE_FROM_JT() // [jumpdest_pc] - - // Store our jumpdest_pc in memory & return it - 0x00 mstore // [] - 0x20 0x00 return -} - -#define macro GET_JUMPDEST_MEM_PACKED_WRAPPER() = takes (0) returns (0) { - __tablestart(TEST_TABLE_PACKED) // [table_start] - 0x04 calldataload // [n, table_start] - - // Store the retrieved jumpdest at 0x00 in memory. - // Since `LOAD_FROM_PACKED_JT` only retrieves 2 bytes - // from the contract's code in the `codecopy` op, we - // need to pass our desired memory pointer + 0x1e (30 bytes) - LOAD_FROM_PACKED_JT(0x1e) // [] - 0x20 0x00 return -} - -#define macro GET_JUMPDEST_STACK_PACKED_WRAPPER() = takes (0) returns (0) { - __tablestart(TEST_TABLE_PACKED) // [table_start] - 0x04 calldataload // [n, table_start] - RETRIEVE_FROM_PACKED_JT() // [jumpdest_pc] - - // Store our jumpdest_pc in memory & return it - 0x00 mstore // [] - 0x20 0x00 return -} - -#define macro MAIN() = takes (0) returns (0) { - pc calldataload 0xE0 shr - dup1 __FUNC_SIG(getJumpdestMem) eq get_jumpdest_mem jumpi - dup1 __FUNC_SIG(getJumpdestStack) eq get_jumpdest_stack jumpi - dup1 __FUNC_SIG(getJumpdestMemPacked) eq get_jumpdest_mem_packed jumpi - dup1 __FUNC_SIG(getJumpdestStackPacked) eq get_jumpdest_stack_packed jumpi - - // Revert if no function signature matched - test_label_d jump - - get_jumpdest_mem: - GET_JUMPDEST_MEM_WRAPPER() - get_jumpdest_stack: - GET_JUMPDEST_MEM_WRAPPER() - get_jumpdest_mem_packed: - GET_JUMPDEST_MEM_PACKED_WRAPPER() - get_jumpdest_stack_packed: - GET_JUMPDEST_STACK_PACKED_WRAPPER() - - // Test labels included in `TEST_TABLE` - test_label_a: - test_label_b: - test_label_c: - test_label_d: - 0x00 dup1 revert -} - - -/// @title JumpTableUtil -/// @notice SPDX-License-Identifier: MIT -/// @author clabby -/// @notice Utility macros for retrieving jumpdest pcs from jump tables - -/// @notice Loads a jumpdest stored in a jumptable into memory at `mem_ptr` -/// -/// @param mem_ptr The memory location to load the 2 byte jumpdest into -/// @param index The index of the jumpdest within the jumptable -/// @param table_start The offset of the jumptable in the contract's bytecode -#define macro LOAD_FROM_JT(mem_ptr) = takes (2) returns (1) { - // Input stack: [index, table_start] - - 0x05 shl add // [table_start + index * 0x20] - 0x20 swap1 // [table_start + index * 0x20, 0x20] - // [mem_ptr, table_start + index * 0x20, 0x20] - codecopy // [] - - // Return stack: [] -} - -/// @notice Retrieves a jumpdest stored in a jumptable and puts it on the stack -/// -/// @param index The index of the jumpdest within the jumptable -/// @param table_start The offset of the jumptable in the contract's bytecode -#define macro RETRIEVE_FROM_JT() = takes (2) returns (1) { - // Input stack: [index, table_start] - - LOAD_FROM_JT(0x00) // [] - 0x00 mload // [res] - - // Return stack: [res] -} - -/// @notice Loads a jumpdest stored in a packed jumptable into memory at `mem_ptr` -/// @dev This macro only loads 2 bytes from the contract code, so make sure to account -/// for this when passing a `mem_ptr`. I.e., if we want to store the jumpdest pc -/// at offset `x`, we would pass in `x + 0x1e` as the `mem_ptr` argument. -/// -/// @param mem_ptr The memory location to load the 2 byte jumpdest into -/// @param index The index of the jumpdest within the packed jumptable -/// @param table_start The offset of the packed jumptable in the contract's bytecode -#define macro LOAD_FROM_PACKED_JT(mem_ptr) = takes (2) returns (1) { - // Input stack: [index, table_start] - - 0x01 shl add // [table_start + index * 0x02] - 0x02 swap1 // [table_start + index * 0x02, 0x02] - // [mem_ptr, table_start + index * 0x02, 0x02] - codecopy // [] - - // Return stack: [] -} - -/// @notice Retrieves a jumpdest stored in a packed jumptable and puts it on the stack -/// -/// @param index The index of the jumpdest within the packed jumptable -/// @param table_start The offset of the packed jumptable in the contract's bytecode -#define macro RETRIEVE_FROM_PACKED_JT() = takes (2) returns (1) { - // Input stack: [index, table_start] - - LOAD_FROM_PACKED_JT(0x1e) - // [] - 0x00 mload // [res] - - // Return stack: [res] -} diff --git a/src/utils/__TEMP__appuiqwhffqjrpihtljpxmlgbwuzstqlMerkleProofLib.huff b/src/utils/__TEMP__appuiqwhffqjrpihtljpxmlgbwuzstqlMerkleProofLib.huff deleted file mode 100644 index f55d7ee8..00000000 --- a/src/utils/__TEMP__appuiqwhffqjrpihtljpxmlgbwuzstqlMerkleProofLib.huff +++ /dev/null @@ -1,86 +0,0 @@ -#define function verifyProof(bytes32, bytes32, bytes32[] calldata) pure returns (bool) - -#define macro VERIFY_PROOF_WRAPPER() = takes (0) returns (0) { - 0x04 calldataload // [root] - 0x24 calldataload // [leaf, root] - 0x64 // [proof_cd_ptr, leaf, root] - VERIFY_PROOF() // [is_valid] - 0x00 mstore // [] - 0x20 0x00 return -} - -#define macro MAIN() = takes (0) returns (0) { - pc calldataload 0xE0 shr - dup1 __FUNC_SIG(verifyProof) eq verifyProof jumpi - - 0x00 dup1 revert - - verifyProof: - VERIFY_PROOF_WRAPPER() -} - - -/// @title MerkleProofLib -/// @notice SPDX-License-Identifier: MIT -/// @author clabby -/// @notice Gas optimized merkle proof verification library -/// @notice Adapted from Solmate (https://github.com/transmissions11/solmate/blob/v7/src/utils/MerkleProofLib.sol) -/// @dev The `proof_cd_ptr` passed via the stack to this macro should point to the offset -/// of the proof array's length in the calldata. This macro assumes that the proof -/// array contains 32 byte values. - -/// @notice Verifies a merkle proof. -/// @param proof_cd_ptr Pointer to the length of the proof array. -/// @param leaf Leaf to prove inclusion of -/// @param root Root of the merkle tree -/// @return is_valid True if the inclusion of `leaf` in the merkle tree represented by -/// `root` was able to be proven, false if not. -#define macro VERIFY_PROOF() = takes (3) returns (1) { - // Input Stack: [proof_cd_ptr, leaf, root] - - // Get ending offset (ptr + 1 + proof_len * 0x20) of proof array - // and its starting offset (ptr + 0x20) - dup1 - 0x20 add - swap1 // [proof_cd_ptr, proof_cd_ptr + 0x20, leaf, root] - calldataload // [proof_arr_len, proof_cd_ptr + 0x20, leaf, root] - 0x05 shl // [proof_arr_len << 5, proof_cd_ptr + 0x20, leaf, root] - dup2 add // [proof_arr_len << 5 + proof_cd_ptr + 0x20, proof_cd_ptr + 0x20, leaf, root] - - // Stack description changed to reflect the vars' respective purposes in the loop - swap1 // [loop_offset, proof_arr_end, computed_hash, root] - - loop: - dup2 dup2 // [loop_offset, proof_arr_end, loop_offset, proof_arr_end, computed_hash, root] - lt // [loop_offset < proof_arr_end, loop_offset, proof_arr_end, computed_hash, root] - // If loop index is >= the proof arr end offset, finish the loop - iszero finish jumpi - - // Load data at proof_arr[loop_offset] - dup1 // [loop_offset, loop_offset, proof_arr_end, computed_hash, root] - calldataload // [proof_arr[loop_offset], loop_offset, proof_arr_end, computed_hash, root] - - dup1 // [proof_arr[loop_offset], proof_arr[loop_offset], loop_offset, proof_arr_end, computed_hash, root] - dup5 // [computed_hash, proof_arr[loop_offset], proof_arr[loop_offset], loop_offset, proof_arr_end, computed_hash, root] - gt // [computed_hash > proof_arr[loop_offset], proof_arr[loop_offset], loop_offset, proof_arr_end, computed_hash, root] - 0x05 shl // [(computed_hash > proof_arr[loop_offset]) << 5, proof_arr[loop_offset], loop_offset, proof_arr_end, computed_hash, root] - - dup5 // [computed_hash, (computed_hash > proof_arr[loop_offset]) << 5, proof_arr[loop_offset], loop_offset, proof_arr_end, computed_hash, root] - dup2 // [(computed_hash > proof_arr[loop_offset]) << 5, computed_hash, (computed_hash > proof_arr[loop_offset]) << 5, proof_arr[loop_offset], loop_offset, proof_arr_end, computed_hash, root] - mstore // [(computed_hash > proof_arr[loop_offset]) << 5, proof_arr[loop_offset], loop_offset, proof_arr_end, computed_hash, root] - - 0x20 xor // [((computed_hash > proof_arr[loop_offset]) << 5) ^ 0x20, proof_arr[loop_offset], loop_offset, proof_arr_end, computed_hash, root] - mstore // [loop_offset, proof_arr_end, computed_hash, root] - - // Compute new hash - 0x40 0x00 sha3 // [computed_hash_new, loop_offset, proof_arr_end, computed_hash, root] - swap3 pop // [loop_offset, proof_arr_end, computed_hash, root] - - // Increment loop offset by 0x20 - 0x20 add // [loop_offset + 0x20, proof_arr_end, computed_hash, root] - - loop jump - finish: - pop pop // [root, computed_hash] - eq // [root == computed_hash] -} \ No newline at end of file diff --git a/src/utils/__TEMP__avabubbndjqnadwlvmuebjtdnnpdjprqConstants.huff b/src/utils/__TEMP__avabubbndjqnadwlvmuebjtdnnpdjprqConstants.huff deleted file mode 100644 index 157180e7..00000000 --- a/src/utils/__TEMP__avabubbndjqnadwlvmuebjtdnnpdjprqConstants.huff +++ /dev/null @@ -1,1789 +0,0 @@ - -// interface -#define function oneWei() pure returns(uint256) -#define function oneGwei() pure returns(uint256) -#define function oneEther() pure returns(uint256) -#define function oneSeconds() pure returns(uint256) -#define function oneMinutes() pure returns(uint256) -#define function oneHours() pure returns(uint256) -#define function oneDays() pure returns(uint256) -#define function oneWeeks() pure returns(uint256) - -#define function uint256Max() pure returns(uint256) -#define function uint248Max() pure returns(uint256) -#define function uint240Max() pure returns(uint256) -#define function uint232Max() pure returns(uint256) -#define function uint224Max() pure returns(uint256) -#define function uint216Max() pure returns(uint256) -#define function uint208Max() pure returns(uint256) -#define function uint200Max() pure returns(uint256) -#define function uint192Max() pure returns(uint256) -#define function uint184Max() pure returns(uint256) -#define function uint176Max() pure returns(uint256) -#define function uint168Max() pure returns(uint256) -#define function uint160Max() pure returns(uint256) -#define function uint152Max() pure returns(uint256) -#define function uint144Max() pure returns(uint256) -#define function uint136Max() pure returns(uint256) -#define function uint128Max() pure returns(uint256) -#define function uint120Max() pure returns(uint256) -#define function uint112Max() pure returns(uint256) -#define function uint104Max() pure returns(uint256) -#define function uint96Max() pure returns(uint256) -#define function uint88Max() pure returns(uint256) -#define function uint80Max() pure returns(uint256) -#define function uint72Max() pure returns(uint256) -#define function uint64Max() pure returns(uint256) -#define function uint56Max() pure returns(uint256) -#define function uint48Max() pure returns(uint256) -#define function uint40Max() pure returns(uint256) -#define function uint32Max() pure returns(uint256) -#define function uint24Max() pure returns(uint256) -#define function uint16Max() pure returns(uint256) -#define function uint8Max() pure returns(uint256) - -#define function int256Max() pure returns(int256) -#define function int248Max() pure returns(int256) -#define function int240Max() pure returns(int256) -#define function int232Max() pure returns(int256) -#define function int224Max() pure returns(int256) -#define function int216Max() pure returns(int256) -#define function int208Max() pure returns(int256) -#define function int200Max() pure returns(int256) -#define function int192Max() pure returns(int256) -#define function int184Max() pure returns(int256) -#define function int176Max() pure returns(int256) -#define function int168Max() pure returns(int256) -#define function int160Max() pure returns(int256) -#define function int152Max() pure returns(int256) -#define function int144Max() pure returns(int256) -#define function int136Max() pure returns(int256) -#define function int128Max() pure returns(int256) -#define function int120Max() pure returns(int256) -#define function int112Max() pure returns(int256) -#define function int104Max() pure returns(int256) -#define function int96Max() pure returns(int256) -#define function int88Max() pure returns(int256) -#define function int80Max() pure returns(int256) -#define function int72Max() pure returns(int256) -#define function int64Max() pure returns(int256) -#define function int56Max() pure returns(int256) -#define function int48Max() pure returns(int256) -#define function int40Max() pure returns(int256) -#define function int32Max() pure returns(int256) -#define function int24Max() pure returns(int256) -#define function int16Max() pure returns(int256) -#define function int8Max() pure returns(int256) - -#define function int256Min() pure returns(int256) -#define function int248Min() pure returns(int256) -#define function int240Min() pure returns(int256) -#define function int232Min() pure returns(int256) -#define function int224Min() pure returns(int256) -#define function int216Min() pure returns(int256) -#define function int208Min() pure returns(int256) -#define function int200Min() pure returns(int256) -#define function int192Min() pure returns(int256) -#define function int184Min() pure returns(int256) -#define function int176Min() pure returns(int256) -#define function int168Min() pure returns(int256) -#define function int160Min() pure returns(int256) -#define function int152Min() pure returns(int256) -#define function int144Min() pure returns(int256) -#define function int136Min() pure returns(int256) -#define function int128Min() pure returns(int256) -#define function int120Min() pure returns(int256) -#define function int112Min() pure returns(int256) -#define function int104Min() pure returns(int256) -#define function int96Min() pure returns(int256) -#define function int88Min() pure returns(int256) -#define function int80Min() pure returns(int256) -#define function int72Min() pure returns(int256) -#define function int64Min() pure returns(int256) -#define function int56Min() pure returns(int256) -#define function int48Min() pure returns(int256) -#define function int40Min() pure returns(int256) -#define function int32Min() pure returns(int256) -#define function int24Min() pure returns(int256) -#define function int16Min() pure returns(int256) -#define function int8Min() pure returns(int256) - -#define function multiWei(uint256) pure returns(uint256) -#define function multiGwei(uint256) pure returns(uint256) -#define function multiEther(uint256) pure returns(uint256) -#define function multiSeconds(uint256) pure returns(uint256) -#define function multiMinutes(uint256) pure returns(uint256) -#define function multiHours(uint256) pure returns(uint256) -#define function multiDays(uint256) pure returns(uint256) -#define function multiWeeks(uint256) pure returns(uint256) - - -#define macro ONE_WEI() = takes(0) returns(0) { - [__ONE_WEI] 0x00 mstore - 0x20 0x00 return -} - -#define macro ONE_GWEI() = takes(0) returns(0) { - [__ONE_GWEI] 0x00 mstore - 0x20 0x00 return -} - -#define macro ONE_ETHER() = takes(0) returns(0) { - [__ONE_ETHER] 0x00 mstore - 0x20 0x00 return -} - -#define macro ONE_SECONDS() = takes(0) returns(0) { - [__ONE_SECONDS] 0x00 mstore - 0x20 0x00 return -} - -#define macro ONE_MINUTES() = takes(0) returns(0) { - [__ONE_MINUTES] 0x00 mstore - 0x20 0x00 return -} - -#define macro ONE_HOURS() = takes(0) returns(0) { - [__ONE_HOURS] 0x00 mstore - 0x20 0x00 return -} - -#define macro ONE_DAYS() = takes(0) returns(0) { - [__ONE_DAYS] 0x00 mstore - 0x20 0x00 return -} - -#define macro ONE_WEEKS() = takes(0) returns(0) { - [__ONE_WEEKS] 0x00 mstore - 0x20 0x00 return -} - - - -#define macro UINT256_MAX() = takes(0) returns(0) { - [__UINT256_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro UINT248_MAX() = takes(0) returns(0) { - [__UINT248_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro UINT240_MAX() = takes(0) returns(0) { - [__UINT240_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro UINT232_MAX() = takes(0) returns(0) { - [__UINT232_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro UINT224_MAX() = takes(0) returns(0) { - [__UINT224_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro UINT216_MAX() = takes(0) returns(0) { - [__UINT216_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro UINT208_MAX() = takes(0) returns(0) { - [__UINT208_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro UINT200_MAX() = takes(0) returns(0) { - [__UINT200_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro UINT192_MAX() = takes(0) returns(0) { - [__UINT192_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro UINT184_MAX() = takes(0) returns(0) { - [__UINT184_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro UINT176_MAX() = takes(0) returns(0) { - [__UINT176_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro UINT168_MAX() = takes(0) returns(0) { - [__UINT168_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro UINT160_MAX() = takes(0) returns(0) { - [__UINT160_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro UINT152_MAX() = takes(0) returns(0) { - [__UINT152_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro UINT144_MAX() = takes(0) returns(0) { - [__UINT144_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro UINT136_MAX() = takes(0) returns(0) { - [__UINT136_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro UINT128_MAX() = takes(0) returns(0) { - [__UINT128_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro UINT120_MAX() = takes(0) returns(0) { - [__UINT120_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro UINT112_MAX() = takes(0) returns(0) { - [__UINT112_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro UINT104_MAX() = takes(0) returns(0) { - [__UINT104_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro UINT96_MAX() = takes(0) returns(0) { - [__UINT96_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro UINT88_MAX() = takes(0) returns(0) { - [__UINT88_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro UINT80_MAX() = takes(0) returns(0) { - [__UINT80_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro UINT72_MAX() = takes(0) returns(0) { - [__UINT72_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro UINT64_MAX() = takes(0) returns(0) { - [__UINT64_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro UINT56_MAX() = takes(0) returns(0) { - [__UINT56_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro UINT48_MAX() = takes(0) returns(0) { - [__UINT48_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro UINT40_MAX() = takes(0) returns(0) { - [__UINT40_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro UINT32_MAX() = takes(0) returns(0) { - [__UINT32_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro UINT24_MAX() = takes(0) returns(0) { - [__UINT24_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro UINT16_MAX() = takes(0) returns(0) { - [__UINT16_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro UINT8_MAX() = takes(0) returns(0) { - [__UINT8_MAX] 0x00 mstore - 0x20 0x00 return -} - - - - - - -#define macro INT256_MAX() = takes(0) returns(0) { - [__INT256_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT248_MAX() = takes(0) returns(0) { - [__INT248_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT240_MAX() = takes(0) returns(0) { - [__INT240_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT232_MAX() = takes(0) returns(0) { - [__INT232_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT224_MAX() = takes(0) returns(0) { - [__INT224_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT216_MAX() = takes(0) returns(0) { - [__INT216_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT208_MAX() = takes(0) returns(0) { - [__INT208_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT200_MAX() = takes(0) returns(0) { - [__INT200_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT192_MAX() = takes(0) returns(0) { - [__INT192_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT184_MAX() = takes(0) returns(0) { - [__INT184_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT176_MAX() = takes(0) returns(0) { - [__INT176_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT168_MAX() = takes(0) returns(0) { - [__INT168_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT160_MAX() = takes(0) returns(0) { - [__INT160_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT152_MAX() = takes(0) returns(0) { - [__INT152_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT144_MAX() = takes(0) returns(0) { - [__INT144_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT136_MAX() = takes(0) returns(0) { - [__INT136_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT128_MAX() = takes(0) returns(0) { - [__INT128_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT120_MAX() = takes(0) returns(0) { - [__INT120_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT112_MAX() = takes(0) returns(0) { - [__INT112_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT104_MAX() = takes(0) returns(0) { - [__INT104_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT96_MAX() = takes(0) returns(0) { - [__INT96_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT88_MAX() = takes(0) returns(0) { - [__INT88_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT80_MAX() = takes(0) returns(0) { - [__INT80_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT72_MAX() = takes(0) returns(0) { - [__INT72_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT64_MAX() = takes(0) returns(0) { - [__INT64_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT56_MAX() = takes(0) returns(0) { - [__INT56_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT48_MAX() = takes(0) returns(0) { - [__INT48_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT40_MAX() = takes(0) returns(0) { - [__INT40_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT32_MAX() = takes(0) returns(0) { - [__INT32_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT24_MAX() = takes(0) returns(0) { - [__INT24_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT16_MAX() = takes(0) returns(0) { - [__INT16_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT8_MAX() = takes(0) returns(0) { - [__INT8_MAX] 0x00 mstore - 0x20 0x00 return -} - - - - - - -#define macro INT256_MIN() = takes(0) returns(0) { - [__INT256_MIN] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT248_MIN() = takes(0) returns(0) { - [__INT248_MIN] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT240_MIN() = takes(0) returns(0) { - [__INT240_MIN] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT232_MIN() = takes(0) returns(0) { - [__INT232_MIN] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT224_MIN() = takes(0) returns(0) { - [__INT224_MIN] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT216_MIN() = takes(0) returns(0) { - [__INT216_MIN] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT208_MIN() = takes(0) returns(0) { - [__INT208_MIN] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT200_MIN() = takes(0) returns(0) { - [__INT200_MIN] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT192_MIN() = takes(0) returns(0) { - [__INT192_MIN] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT184_MIN() = takes(0) returns(0) { - [__INT184_MIN] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT176_MIN() = takes(0) returns(0) { - [__INT176_MIN] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT168_MIN() = takes(0) returns(0) { - [__INT168_MIN] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT160_MIN() = takes(0) returns(0) { - [__INT160_MIN] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT152_MIN() = takes(0) returns(0) { - [__INT152_MIN] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT144_MIN() = takes(0) returns(0) { - [__INT144_MIN] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT136_MIN() = takes(0) returns(0) { - [__INT136_MIN] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT128_MIN() = takes(0) returns(0) { - [__INT128_MIN] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT120_MIN() = takes(0) returns(0) { - [__INT120_MIN] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT112_MIN() = takes(0) returns(0) { - [__INT112_MIN] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT104_MIN() = takes(0) returns(0) { - [__INT104_MIN] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT96_MIN() = takes(0) returns(0) { - [__INT96_MIN] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT88_MIN() = takes(0) returns(0) { - [__INT88_MIN] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT80_MIN() = takes(0) returns(0) { - [__INT80_MIN] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT72_MIN() = takes(0) returns(0) { - [__INT72_MIN] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT64_MIN() = takes(0) returns(0) { - [__INT64_MIN] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT56_MIN() = takes(0) returns(0) { - [__INT56_MIN] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT48_MIN() = takes(0) returns(0) { - [__INT48_MIN] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT40_MIN() = takes(0) returns(0) { - [__INT40_MIN] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT32_MIN() = takes(0) returns(0) { - [__INT32_MIN] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT24_MIN() = takes(0) returns(0) { - [__INT24_MIN] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT16_MIN() = takes(0) returns(0) { - [__INT16_MIN] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT8_MIN() = takes(0) returns(0) { - [__INT8_MIN] 0x00 mstore - 0x20 0x00 return -} - - - - -#define macro MULTI_WEI() = takes(0) returns(0) { - 0x04 calldataload __WEI() 0x00 mstore - 0x20 0x00 return -} - -#define macro MULTI_GWEI() = takes(0) returns(0) { - 0x04 calldataload __GWEI() 0x00 mstore - 0x20 0x00 return -} - -#define macro MULTI_ETHER() = takes(0) returns(0) { - 0x04 calldataload __ETHER() 0x00 mstore - 0x20 0x00 return -} - -#define macro MULTI_SECONDS() = takes(0) returns(0) { - 0x04 calldataload __SECONDS() 0x00 mstore - 0x20 0x00 return -} - -#define macro MULTI_MINUTES() = takes(0) returns(0) { - 0x04 calldataload __MINUTES() 0x00 mstore - 0x20 0x00 return -} - -#define macro MULTI_HOURS() = takes(0) returns(0) { - 0x04 calldataload __HOURS() 0x00 mstore - 0x20 0x00 return -} - -#define macro MULTI_DAYS() = takes(0) returns(0) { - 0x04 calldataload __DAYS() 0x00 mstore - 0x20 0x00 return -} - -#define macro MULTI_WEEKS() = takes(0) returns(0) { - 0x04 calldataload __WEEKS() 0x00 mstore - 0x20 0x00 return -} - - - - - - - - - -// Function Dispatching -#define macro MAIN() = takes (1) returns (1) { - // Identify which function is being called. - // [func sig] - 0x00 calldataload 0xE0 shr - - - // function int104Max() pure returns (int256) - dup1 __FUNC_SIG(int104Max) eq int104MaxJump jumpi - - - // function int104Min() pure returns (int256) - dup1 __FUNC_SIG(int104Min) eq int104MinJump jumpi - - - // function int112Max() pure returns (int256) - dup1 __FUNC_SIG(int112Max) eq int112MaxJump jumpi - - - // function int112Min() pure returns (int256) - dup1 __FUNC_SIG(int112Min) eq int112MinJump jumpi - - - // function int120Max() pure returns (int256) - dup1 __FUNC_SIG(int120Max) eq int120MaxJump jumpi - - - // function int120Min() pure returns (int256) - dup1 __FUNC_SIG(int120Min) eq int120MinJump jumpi - - - // function int128Max() pure returns (int256) - dup1 __FUNC_SIG(int128Max) eq int128MaxJump jumpi - - - // function int128Min() pure returns (int256) - dup1 __FUNC_SIG(int128Min) eq int128MinJump jumpi - - - // function int136Max() pure returns (int256) - dup1 __FUNC_SIG(int136Max) eq int136MaxJump jumpi - - - // function int136Min() pure returns (int256) - dup1 __FUNC_SIG(int136Min) eq int136MinJump jumpi - - - // function int144Max() pure returns (int256) - dup1 __FUNC_SIG(int144Max) eq int144MaxJump jumpi - - - // function int144Min() pure returns (int256) - dup1 __FUNC_SIG(int144Min) eq int144MinJump jumpi - - - // function int152Max() pure returns (int256) - dup1 __FUNC_SIG(int152Max) eq int152MaxJump jumpi - - - // function int152Min() pure returns (int256) - dup1 __FUNC_SIG(int152Min) eq int152MinJump jumpi - - - // function int160Max() pure returns (int256) - dup1 __FUNC_SIG(int160Max) eq int160MaxJump jumpi - - - // function int160Min() pure returns (int256) - dup1 __FUNC_SIG(int160Min) eq int160MinJump jumpi - - - // function int168Max() pure returns (int256) - dup1 __FUNC_SIG(int168Max) eq int168MaxJump jumpi - - - // function int168Min() pure returns (int256) - dup1 __FUNC_SIG(int168Min) eq int168MinJump jumpi - - - // function int16Max() pure returns (int256) - dup1 __FUNC_SIG(int16Max) eq int16MaxJump jumpi - - - // function int16Min() pure returns (int256) - dup1 __FUNC_SIG(int16Min) eq int16MinJump jumpi - - - // function int176Max() pure returns (int256) - dup1 __FUNC_SIG(int176Max) eq int176MaxJump jumpi - - - // function int176Min() pure returns (int256) - dup1 __FUNC_SIG(int176Min) eq int176MinJump jumpi - - - // function int184Max() pure returns (int256) - dup1 __FUNC_SIG(int184Max) eq int184MaxJump jumpi - - - // function int184Min() pure returns (int256) - dup1 __FUNC_SIG(int184Min) eq int184MinJump jumpi - - - // function int192Max() pure returns (int256) - dup1 __FUNC_SIG(int192Max) eq int192MaxJump jumpi - - - // function int192Min() pure returns (int256) - dup1 __FUNC_SIG(int192Min) eq int192MinJump jumpi - - - // function int200Max() pure returns (int256) - dup1 __FUNC_SIG(int200Max) eq int200MaxJump jumpi - - - // function int200Min() pure returns (int256) - dup1 __FUNC_SIG(int200Min) eq int200MinJump jumpi - - - // function int208Max() pure returns (int256) - dup1 __FUNC_SIG(int208Max) eq int208MaxJump jumpi - - - // function int208Min() pure returns (int256) - dup1 __FUNC_SIG(int208Min) eq int208MinJump jumpi - - - // function int216Max() pure returns (int256) - dup1 __FUNC_SIG(int216Max) eq int216MaxJump jumpi - - - // function int216Min() pure returns (int256) - dup1 __FUNC_SIG(int216Min) eq int216MinJump jumpi - - - // function int224Max() pure returns (int256) - dup1 __FUNC_SIG(int224Max) eq int224MaxJump jumpi - - - // function int224Min() pure returns (int256) - dup1 __FUNC_SIG(int224Min) eq int224MinJump jumpi - - - // function int232Max() pure returns (int256) - dup1 __FUNC_SIG(int232Max) eq int232MaxJump jumpi - - - // function int232Min() pure returns (int256) - dup1 __FUNC_SIG(int232Min) eq int232MinJump jumpi - - - // function int240Max() pure returns (int256) - dup1 __FUNC_SIG(int240Max) eq int240MaxJump jumpi - - - // function int240Min() pure returns (int256) - dup1 __FUNC_SIG(int240Min) eq int240MinJump jumpi - - - // function int248Max() pure returns (int256) - dup1 __FUNC_SIG(int248Max) eq int248MaxJump jumpi - - - // function int248Min() pure returns (int256) - dup1 __FUNC_SIG(int248Min) eq int248MinJump jumpi - - - // function int24Max() pure returns (int256) - dup1 __FUNC_SIG(int24Max) eq int24MaxJump jumpi - - - // function int24Min() pure returns (int256) - dup1 __FUNC_SIG(int24Min) eq int24MinJump jumpi - - - // function int256Max() pure returns (int256) - dup1 __FUNC_SIG(int256Max) eq int256MaxJump jumpi - - - // function int256Min() pure returns (int256) - dup1 __FUNC_SIG(int256Min) eq int256MinJump jumpi - - - // function int32Max() pure returns (int256) - dup1 __FUNC_SIG(int32Max) eq int32MaxJump jumpi - - - // function int32Min() pure returns (int256) - dup1 __FUNC_SIG(int32Min) eq int32MinJump jumpi - - - // function int40Max() pure returns (int256) - dup1 __FUNC_SIG(int40Max) eq int40MaxJump jumpi - - - // function int40Min() pure returns (int256) - dup1 __FUNC_SIG(int40Min) eq int40MinJump jumpi - - - // function int48Max() pure returns (int256) - dup1 __FUNC_SIG(int48Max) eq int48MaxJump jumpi - - - // function int48Min() pure returns (int256) - dup1 __FUNC_SIG(int48Min) eq int48MinJump jumpi - - - // function int56Max() pure returns (int256) - dup1 __FUNC_SIG(int56Max) eq int56MaxJump jumpi - - - // function int56Min() pure returns (int256) - dup1 __FUNC_SIG(int56Min) eq int56MinJump jumpi - - - // function int64Max() pure returns (int256) - dup1 __FUNC_SIG(int64Max) eq int64MaxJump jumpi - - - // function int64Min() pure returns (int256) - dup1 __FUNC_SIG(int64Min) eq int64MinJump jumpi - - - // function int72Max() pure returns (int256) - dup1 __FUNC_SIG(int72Max) eq int72MaxJump jumpi - - - // function int72Min() pure returns (int256) - dup1 __FUNC_SIG(int72Min) eq int72MinJump jumpi - - - // function int80Max() pure returns (int256) - dup1 __FUNC_SIG(int80Max) eq int80MaxJump jumpi - - - // function int80Min() pure returns (int256) - dup1 __FUNC_SIG(int80Min) eq int80MinJump jumpi - - - // function int88Max() pure returns (int256) - dup1 __FUNC_SIG(int88Max) eq int88MaxJump jumpi - - - // function int88Min() pure returns (int256) - dup1 __FUNC_SIG(int88Min) eq int88MinJump jumpi - - - // function int8Max() pure returns (int256) - dup1 __FUNC_SIG(int8Max) eq int8MaxJump jumpi - - - // function int8Min() pure returns (int256) - dup1 __FUNC_SIG(int8Min) eq int8MinJump jumpi - - - // function int96Max() pure returns (int256) - dup1 __FUNC_SIG(int96Max) eq int96MaxJump jumpi - - - // function int96Min() pure returns (int256) - dup1 __FUNC_SIG(int96Min) eq int96MinJump jumpi - - - // function multiDays(uint256) pure returns (uint256) - dup1 __FUNC_SIG(multiDays) eq multiDaysJump jumpi - - - // function multiEther(uint256) pure returns (uint256) - dup1 __FUNC_SIG(multiEther) eq multiEtherJump jumpi - - - // function multiGwei(uint256) pure returns (uint256) - dup1 __FUNC_SIG(multiGwei) eq multiGweiJump jumpi - - - // function multiHours(uint256) pure returns (uint256) - dup1 __FUNC_SIG(multiHours) eq multiHoursJump jumpi - - - // function multiMinutes(uint256) pure returns (uint256) - dup1 __FUNC_SIG(multiMinutes) eq multiMinutesJump jumpi - - - // function multiSeconds(uint256) pure returns (uint256) - dup1 __FUNC_SIG(multiSeconds) eq multiSecondsJump jumpi - - - // function multiWeeks(uint256) pure returns (uint256) - dup1 __FUNC_SIG(multiWeeks) eq multiWeeksJump jumpi - - - // function multiWei(uint256) pure returns (uint256) - dup1 __FUNC_SIG(multiWei) eq multiWeiJump jumpi - - - // function oneDays() pure returns (uint256) - dup1 __FUNC_SIG(oneDays) eq oneDaysJump jumpi - - - // function oneEther() pure returns (uint256) - dup1 __FUNC_SIG(oneEther) eq oneEtherJump jumpi - - - // function oneGwei() pure returns (uint256) - dup1 __FUNC_SIG(oneGwei) eq oneGweiJump jumpi - - - // function oneHours() pure returns (uint256) - dup1 __FUNC_SIG(oneHours) eq oneHoursJump jumpi - - - // function oneMinutes() pure returns (uint256) - dup1 __FUNC_SIG(oneMinutes) eq oneMinutesJump jumpi - - - // function oneSeconds() pure returns (uint256) - dup1 __FUNC_SIG(oneSeconds) eq oneSecondsJump jumpi - - - // function oneWeeks() pure returns (uint256) - dup1 __FUNC_SIG(oneWeeks) eq oneWeeksJump jumpi - - - // function oneWei() pure returns (uint256) - dup1 __FUNC_SIG(oneWei) eq oneWeiJump jumpi - - - // function uint104Max() pure returns (uint256) - dup1 __FUNC_SIG(uint104Max) eq uint104MaxJump jumpi - - - // function uint112Max() pure returns (uint256) - dup1 __FUNC_SIG(uint112Max) eq uint112MaxJump jumpi - - - // function uint120Max() pure returns (uint256) - dup1 __FUNC_SIG(uint120Max) eq uint120MaxJump jumpi - - - // function uint128Max() pure returns (uint256) - dup1 __FUNC_SIG(uint128Max) eq uint128MaxJump jumpi - - - // function uint136Max() pure returns (uint256) - dup1 __FUNC_SIG(uint136Max) eq uint136MaxJump jumpi - - - // function uint144Max() pure returns (uint256) - dup1 __FUNC_SIG(uint144Max) eq uint144MaxJump jumpi - - - // function uint152Max() pure returns (uint256) - dup1 __FUNC_SIG(uint152Max) eq uint152MaxJump jumpi - - - // function uint160Max() pure returns (uint256) - dup1 __FUNC_SIG(uint160Max) eq uint160MaxJump jumpi - - - // function uint168Max() pure returns (uint256) - dup1 __FUNC_SIG(uint168Max) eq uint168MaxJump jumpi - - - // function uint16Max() pure returns (uint256) - dup1 __FUNC_SIG(uint16Max) eq uint16MaxJump jumpi - - - // function uint176Max() pure returns (uint256) - dup1 __FUNC_SIG(uint176Max) eq uint176MaxJump jumpi - - - // function uint184Max() pure returns (uint256) - dup1 __FUNC_SIG(uint184Max) eq uint184MaxJump jumpi - - - // function uint192Max() pure returns (uint256) - dup1 __FUNC_SIG(uint192Max) eq uint192MaxJump jumpi - - - // function uint200Max() pure returns (uint256) - dup1 __FUNC_SIG(uint200Max) eq uint200MaxJump jumpi - - - // function uint208Max() pure returns (uint256) - dup1 __FUNC_SIG(uint208Max) eq uint208MaxJump jumpi - - - // function uint216Max() pure returns (uint256) - dup1 __FUNC_SIG(uint216Max) eq uint216MaxJump jumpi - - - // function uint224Max() pure returns (uint256) - dup1 __FUNC_SIG(uint224Max) eq uint224MaxJump jumpi - - - // function uint232Max() pure returns (uint256) - dup1 __FUNC_SIG(uint232Max) eq uint232MaxJump jumpi - - - // function uint240Max() pure returns (uint256) - dup1 __FUNC_SIG(uint240Max) eq uint240MaxJump jumpi - - - // function uint248Max() pure returns (uint256) - dup1 __FUNC_SIG(uint248Max) eq uint248MaxJump jumpi - - - // function uint24Max() pure returns (uint256) - dup1 __FUNC_SIG(uint24Max) eq uint24MaxJump jumpi - - - // function uint256Max() pure returns (uint256) - dup1 __FUNC_SIG(uint256Max) eq uint256MaxJump jumpi - - - // function uint32Max() pure returns (uint256) - dup1 __FUNC_SIG(uint32Max) eq uint32MaxJump jumpi - - - // function uint40Max() pure returns (uint256) - dup1 __FUNC_SIG(uint40Max) eq uint40MaxJump jumpi - - - // function uint48Max() pure returns (uint256) - dup1 __FUNC_SIG(uint48Max) eq uint48MaxJump jumpi - - - // function uint56Max() pure returns (uint256) - dup1 __FUNC_SIG(uint56Max) eq uint56MaxJump jumpi - - - // function uint64Max() pure returns (uint256) - dup1 __FUNC_SIG(uint64Max) eq uint64MaxJump jumpi - - - // function uint72Max() pure returns (uint256) - dup1 __FUNC_SIG(uint72Max) eq uint72MaxJump jumpi - - - // function uint80Max() pure returns (uint256) - dup1 __FUNC_SIG(uint80Max) eq uint80MaxJump jumpi - - - // function uint88Max() pure returns (uint256) - dup1 __FUNC_SIG(uint88Max) eq uint88MaxJump jumpi - - - // function uint8Max() pure returns (uint256) - dup1 __FUNC_SIG(uint8Max) eq uint8MaxJump jumpi - - - // function uint96Max() pure returns (uint256) - dup1 __FUNC_SIG(uint96Max) eq uint96MaxJump jumpi - - not_found: - // Revert if no match is found. - 0x00 dup1 revert - - - // function uint168Max() pure returns (uint256) - uint168MaxJump: - UINT168_MAX() - - // function int184Max() pure returns (int256) - int184MaxJump: - INT184_MAX() - - // function int40Max() pure returns (int256) - int40MaxJump: - INT40_MAX() - - // function oneWeeks() pure returns (uint256) - oneWeeksJump: - ONE_WEEKS() - - // function uint160Max() pure returns (uint256) - uint160MaxJump: - UINT160_MAX() - - // function int176Min() pure returns (int256) - int176MinJump: - INT176_MIN() - - // function int88Max() pure returns (int256) - int88MaxJump: - INT88_MAX() - - // function int168Min() pure returns (int256) - int168MinJump: - INT168_MIN() - - // function int208Min() pure returns (int256) - int208MinJump: - INT208_MIN() - - // function uint104Max() pure returns (uint256) - uint104MaxJump: - UINT104_MAX() - - // function int24Min() pure returns (int256) - int24MinJump: - INT24_MIN() - - // function int112Min() pure returns (int256) - int112MinJump: - INT112_MIN() - - // function int96Max() pure returns (int256) - int96MaxJump: - INT96_MAX() - - // function int96Min() pure returns (int256) - int96MinJump: - INT96_MIN() - - // function uint128Max() pure returns (uint256) - uint128MaxJump: - UINT128_MAX() - - // function uint200Max() pure returns (uint256) - uint200MaxJump: - UINT200_MAX() - - // function oneHours() pure returns (uint256) - oneHoursJump: - ONE_HOURS() - - // function int144Min() pure returns (int256) - int144MinJump: - INT144_MIN() - - // function uint24Max() pure returns (uint256) - uint24MaxJump: - UINT24_MAX() - - // function uint120Max() pure returns (uint256) - uint120MaxJump: - UINT120_MAX() - - // function int256Max() pure returns (int256) - int256MaxJump: - INT256_MAX() - - // function int136Max() pure returns (int256) - int136MaxJump: - INT136_MAX() - - // function int216Max() pure returns (int256) - int216MaxJump: - INT216_MAX() - - // function int144Max() pure returns (int256) - int144MaxJump: - INT144_MAX() - - // function int72Min() pure returns (int256) - int72MinJump: - INT72_MIN() - - // function oneWei() pure returns (uint256) - oneWeiJump: - ONE_WEI() - - // function multiDays(uint256) pure returns (uint256) - multiDaysJump: - MULTI_DAYS() - - // function int64Min() pure returns (int256) - int64MinJump: - INT64_MIN() - - // function uint248Max() pure returns (uint256) - uint248MaxJump: - UINT248_MAX() - - // function int24Max() pure returns (int256) - int24MaxJump: - INT24_MAX() - - // function uint176Max() pure returns (uint256) - uint176MaxJump: - UINT176_MAX() - - // function int32Max() pure returns (int256) - int32MaxJump: - INT32_MAX() - - // function int232Max() pure returns (int256) - int232MaxJump: - INT232_MAX() - - // function int48Min() pure returns (int256) - int48MinJump: - INT48_MIN() - - // function multiSeconds(uint256) pure returns (uint256) - multiSecondsJump: - MULTI_SECONDS() - - // function int224Min() pure returns (int256) - int224MinJump: - INT224_MIN() - - // function int216Min() pure returns (int256) - int216MinJump: - INT216_MIN() - - // function int88Min() pure returns (int256) - int88MinJump: - INT88_MIN() - - // function uint136Max() pure returns (uint256) - uint136MaxJump: - UINT136_MAX() - - // function int248Min() pure returns (int256) - int248MinJump: - INT248_MIN() - - // function int176Max() pure returns (int256) - int176MaxJump: - INT176_MAX() - - // function uint8Max() pure returns (uint256) - uint8MaxJump: - UINT8_MAX() - - // function int56Max() pure returns (int256) - int56MaxJump: - INT56_MAX() - - // function int80Min() pure returns (int256) - int80MinJump: - INT80_MIN() - - // function int200Min() pure returns (int256) - int200MinJump: - INT200_MIN() - - // function uint48Max() pure returns (uint256) - uint48MaxJump: - UINT48_MAX() - - // function int192Max() pure returns (int256) - int192MaxJump: - INT192_MAX() - - // function int208Max() pure returns (int256) - int208MaxJump: - INT208_MAX() - - // function int40Min() pure returns (int256) - int40MinJump: - INT40_MIN() - - // function int192Min() pure returns (int256) - int192MinJump: - INT192_MIN() - - // function int64Max() pure returns (int256) - int64MaxJump: - INT64_MAX() - - // function multiHours(uint256) pure returns (uint256) - multiHoursJump: - MULTI_HOURS() - - // function int16Max() pure returns (int256) - int16MaxJump: - INT16_MAX() - - // function multiEther(uint256) pure returns (uint256) - multiEtherJump: - MULTI_ETHER() - - // function uint64Max() pure returns (uint256) - uint64MaxJump: - UINT64_MAX() - - // function uint216Max() pure returns (uint256) - uint216MaxJump: - UINT216_MAX() - - // function int248Max() pure returns (int256) - int248MaxJump: - INT248_MAX() - - // function int184Min() pure returns (int256) - int184MinJump: - INT184_MIN() - - // function oneGwei() pure returns (uint256) - oneGweiJump: - ONE_GWEI() - - // function int136Min() pure returns (int256) - int136MinJump: - INT136_MIN() - - // function int104Min() pure returns (int256) - int104MinJump: - INT104_MIN() - - // function uint40Max() pure returns (uint256) - uint40MaxJump: - UINT40_MAX() - - // function uint96Max() pure returns (uint256) - uint96MaxJump: - UINT96_MAX() - - // function multiMinutes(uint256) pure returns (uint256) - multiMinutesJump: - MULTI_MINUTES() - - // function uint72Max() pure returns (uint256) - uint72MaxJump: - UINT72_MAX() - - // function int56Min() pure returns (int256) - int56MinJump: - INT56_MIN() - - // function multiGwei(uint256) pure returns (uint256) - multiGweiJump: - MULTI_GWEI() - - // function int232Min() pure returns (int256) - int232MinJump: - INT232_MIN() - - // function uint224Max() pure returns (uint256) - uint224MaxJump: - UINT224_MAX() - - // function uint80Max() pure returns (uint256) - uint80MaxJump: - UINT80_MAX() - - // function int16Min() pure returns (int256) - int16MinJump: - INT16_MIN() - - // function int120Max() pure returns (int256) - int120MaxJump: - INT120_MAX() - - // function uint152Max() pure returns (uint256) - uint152MaxJump: - UINT152_MAX() - - // function multiWei(uint256) pure returns (uint256) - multiWeiJump: - MULTI_WEI() - - // function int200Max() pure returns (int256) - int200MaxJump: - INT200_MAX() - - // function uint144Max() pure returns (uint256) - uint144MaxJump: - UINT144_MAX() - - // function uint32Max() pure returns (uint256) - uint32MaxJump: - UINT32_MAX() - - // function uint184Max() pure returns (uint256) - uint184MaxJump: - UINT184_MAX() - - // function int128Min() pure returns (int256) - int128MinJump: - INT128_MIN() - - // function uint16Max() pure returns (uint256) - uint16MaxJump: - UINT16_MAX() - - // function int160Max() pure returns (int256) - int160MaxJump: - INT160_MAX() - - // function uint208Max() pure returns (uint256) - uint208MaxJump: - UINT208_MAX() - - // function int168Max() pure returns (int256) - int168MaxJump: - INT168_MAX() - - // function oneDays() pure returns (uint256) - oneDaysJump: - ONE_DAYS() - - // function oneMinutes() pure returns (uint256) - oneMinutesJump: - ONE_MINUTES() - - // function int120Min() pure returns (int256) - int120MinJump: - INT120_MIN() - - // function oneSeconds() pure returns (uint256) - oneSecondsJump: - ONE_SECONDS() - - // function int8Max() pure returns (int256) - int8MaxJump: - INT8_MAX() - - // function uint112Max() pure returns (uint256) - uint112MaxJump: - UINT112_MAX() - - // function int8Min() pure returns (int256) - int8MinJump: - INT8_MIN() - - // function oneEther() pure returns (uint256) - oneEtherJump: - ONE_ETHER() - - // function int72Max() pure returns (int256) - int72MaxJump: - INT72_MAX() - - // function int240Max() pure returns (int256) - int240MaxJump: - INT240_MAX() - - // function multiWeeks(uint256) pure returns (uint256) - multiWeeksJump: - MULTI_WEEKS() - - // function int32Min() pure returns (int256) - int32MinJump: - INT32_MIN() - - // function int80Max() pure returns (int256) - int80MaxJump: - INT80_MAX() - - // function int160Min() pure returns (int256) - int160MinJump: - INT160_MIN() - - // function uint256Max() pure returns (uint256) - uint256MaxJump: - UINT256_MAX() - - // function uint240Max() pure returns (uint256) - uint240MaxJump: - UINT240_MAX() - - // function uint192Max() pure returns (uint256) - uint192MaxJump: - UINT192_MAX() - - // function int112Max() pure returns (int256) - int112MaxJump: - INT112_MAX() - - // function uint56Max() pure returns (uint256) - uint56MaxJump: - UINT56_MAX() - - // function int256Min() pure returns (int256) - int256MinJump: - INT256_MIN() - - // function int48Max() pure returns (int256) - int48MaxJump: - INT48_MAX() - - // function int224Max() pure returns (int256) - int224MaxJump: - INT224_MAX() - - // function int128Max() pure returns (int256) - int128MaxJump: - INT128_MAX() - - // function int152Max() pure returns (int256) - int152MaxJump: - INT152_MAX() - - // function int240Min() pure returns (int256) - int240MinJump: - INT240_MIN() - - // function uint232Max() pure returns (uint256) - uint232MaxJump: - UINT232_MAX() - - // function int104Max() pure returns (int256) - int104MaxJump: - INT104_MAX() - - // function uint88Max() pure returns (uint256) - uint88MaxJump: - UINT88_MAX() - - // function int152Min() pure returns (int256) - int152MinJump: - INT152_MIN() -} - -/// @title Constants -/// @notice SPDX-License-Identifier: MIT -/// @author AmadiMichael -/// @notice common constants found in solidity and helpers in huff - - -// value constants -#define constant __ONE_WEI = 0x01 -#define constant __ONE_GWEI = 0x3b9aca00 -#define constant __ONE_ETHER = 0xde0b6b3a7640000 - - -// time constants -#define constant __ONE_SECONDS = 0x01 -#define constant __ONE_MINUTES = 0x3c -#define constant __ONE_HOURS = 0xe10 -#define constant __ONE_DAYS = 0x15180 -#define constant __ONE_WEEKS = 0x93a80 - - -// type ranges constants -#define constant __UINT256_MAX = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -#define constant __UINT248_MAX = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -#define constant __UINT240_MAX = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -#define constant __UINT232_MAX = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -#define constant __UINT224_MAX = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffff -#define constant __UINT216_MAX = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffff -#define constant __UINT208_MAX = 0xffffffffffffffffffffffffffffffffffffffffffffffffffff -#define constant __UINT200_MAX = 0xffffffffffffffffffffffffffffffffffffffffffffffffff -#define constant __UINT192_MAX = 0xffffffffffffffffffffffffffffffffffffffffffffffff -#define constant __UINT184_MAX = 0xffffffffffffffffffffffffffffffffffffffffffffff -#define constant __UINT176_MAX = 0xffffffffffffffffffffffffffffffffffffffffffff -#define constant __UINT168_MAX = 0xffffffffffffffffffffffffffffffffffffffffff -#define constant __UINT160_MAX = 0xffffffffffffffffffffffffffffffffffffffff -#define constant __UINT152_MAX = 0xffffffffffffffffffffffffffffffffffffff -#define constant __UINT144_MAX = 0xffffffffffffffffffffffffffffffffffff -#define constant __UINT136_MAX = 0xffffffffffffffffffffffffffffffffff -#define constant __UINT128_MAX = 0xffffffffffffffffffffffffffffffff -#define constant __UINT120_MAX = 0xffffffffffffffffffffffffffffff -#define constant __UINT112_MAX = 0xffffffffffffffffffffffffffff -#define constant __UINT104_MAX = 0xffffffffffffffffffffffffff -#define constant __UINT96_MAX = 0xffffffffffffffffffffffff -#define constant __UINT88_MAX = 0xffffffffffffffffffffff -#define constant __UINT80_MAX = 0xffffffffffffffffffff -#define constant __UINT72_MAX = 0xffffffffffffffffff -#define constant __UINT64_MAX = 0xffffffffffffffff -#define constant __UINT56_MAX = 0xffffffffffffff -#define constant __UINT48_MAX = 0xffffffffffff -#define constant __UINT40_MAX = 0xffffffffff -#define constant __UINT32_MAX = 0xffffffff -#define constant __UINT24_MAX = 0xffffff -#define constant __UINT16_MAX = 0xffff -#define constant __UINT8_MAX = 0xff - - -#define constant __INT256_MAX = 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -#define constant __INT248_MAX = 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -#define constant __INT240_MAX = 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -#define constant __INT232_MAX = 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffff -#define constant __INT224_MAX = 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffff -#define constant __INT216_MAX = 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffff -#define constant __INT208_MAX = 0x7fffffffffffffffffffffffffffffffffffffffffffffffffff -#define constant __INT200_MAX = 0x7fffffffffffffffffffffffffffffffffffffffffffffffff -#define constant __INT192_MAX = 0x7fffffffffffffffffffffffffffffffffffffffffffffff -#define constant __INT184_MAX = 0x7fffffffffffffffffffffffffffffffffffffffffffff -#define constant __INT176_MAX = 0x7fffffffffffffffffffffffffffffffffffffffffff -#define constant __INT168_MAX = 0x7fffffffffffffffffffffffffffffffffffffffff -#define constant __INT160_MAX = 0x7fffffffffffffffffffffffffffffffffffffff -#define constant __INT152_MAX = 0x7fffffffffffffffffffffffffffffffffffff -#define constant __INT144_MAX = 0x7fffffffffffffffffffffffffffffffffff -#define constant __INT136_MAX = 0x7fffffffffffffffffffffffffffffffff -#define constant __INT128_MAX = 0x7fffffffffffffffffffffffffffffff -#define constant __INT120_MAX = 0x7fffffffffffffffffffffffffffff -#define constant __INT112_MAX = 0x7fffffffffffffffffffffffffff -#define constant __INT104_MAX = 0x7fffffffffffffffffffffffff -#define constant __INT96_MAX = 0x7fffffffffffffffffffffff -#define constant __INT88_MAX = 0x7fffffffffffffffffffff -#define constant __INT80_MAX = 0x7fffffffffffffffffff -#define constant __INT72_MAX = 0x7fffffffffffffffff -#define constant __INT64_MAX = 0x7fffffffffffffff -#define constant __INT56_MAX = 0x7fffffffffffff -#define constant __INT48_MAX = 0x7fffffffffff -#define constant __INT40_MAX = 0x7fffffffff -#define constant __INT32_MAX = 0x7fffffff -#define constant __INT24_MAX = 0x7fffff -#define constant __INT16_MAX = 0x7fff -#define constant __INT8_MAX = 0x7f - -#define constant __INT256_MIN = 0x8000000000000000000000000000000000000000000000000000000000000000 -#define constant __INT248_MIN = 0xff80000000000000000000000000000000000000000000000000000000000000 -#define constant __INT240_MIN = 0xffff800000000000000000000000000000000000000000000000000000000000 -#define constant __INT232_MIN = 0xffffff8000000000000000000000000000000000000000000000000000000000 -#define constant __INT224_MIN = 0xffffffff80000000000000000000000000000000000000000000000000000000 -#define constant __INT216_MIN = 0xffffffffff800000000000000000000000000000000000000000000000000000 -#define constant __INT208_MIN = 0xffffffffffff8000000000000000000000000000000000000000000000000000 -#define constant __INT200_MIN = 0xffffffffffffff80000000000000000000000000000000000000000000000000 -#define constant __INT192_MIN = 0xffffffffffffffff800000000000000000000000000000000000000000000000 -#define constant __INT184_MIN = 0xffffffffffffffffff8000000000000000000000000000000000000000000000 -#define constant __INT176_MIN = 0xffffffffffffffffffff80000000000000000000000000000000000000000000 -#define constant __INT168_MIN = 0xffffffffffffffffffffff800000000000000000000000000000000000000000 -#define constant __INT160_MIN = 0xffffffffffffffffffffffff8000000000000000000000000000000000000000 -#define constant __INT152_MIN = 0xffffffffffffffffffffffffff80000000000000000000000000000000000000 -#define constant __INT144_MIN = 0xffffffffffffffffffffffffffff800000000000000000000000000000000000 -#define constant __INT136_MIN = 0xffffffffffffffffffffffffffffff8000000000000000000000000000000000 -#define constant __INT128_MIN = 0xffffffffffffffffffffffffffffffff80000000000000000000000000000000 -#define constant __INT120_MIN = 0xffffffffffffffffffffffffffffffffff800000000000000000000000000000 -#define constant __INT112_MIN = 0xffffffffffffffffffffffffffffffffffff8000000000000000000000000000 -#define constant __INT104_MIN = 0xffffffffffffffffffffffffffffffffffffff80000000000000000000000000 -#define constant __INT96_MIN = 0xffffffffffffffffffffffffffffffffffffffff800000000000000000000000 -#define constant __INT88_MIN = 0xffffffffffffffffffffffffffffffffffffffffff8000000000000000000000 -#define constant __INT80_MIN = 0xffffffffffffffffffffffffffffffffffffffffffff80000000000000000000 -#define constant __INT72_MIN = 0xffffffffffffffffffffffffffffffffffffffffffffff800000000000000000 -#define constant __INT64_MIN = 0xffffffffffffffffffffffffffffffffffffffffffffffff8000000000000000 -#define constant __INT56_MIN = 0xffffffffffffffffffffffffffffffffffffffffffffffffff80000000000000 -#define constant __INT48_MIN = 0xffffffffffffffffffffffffffffffffffffffffffffffffffff800000000000 -#define constant __INT40_MIN = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffff8000000000 -#define constant __INT32_MIN = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffff80000000 -#define constant __INT24_MIN = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffff800000 -#define constant __INT16_MIN = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8000 -#define constant __INT8_MIN = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80 - - - -// value helpers -// if you don't mind an extra 8 gas then these helper functions can be "helpful" - - -#define macro __WEI() = takes(1) returns(1) { - // expects at least one item on the stack (amount(x) of wei) - // [x, ...] - [__ONE_WEI] mul // [x_wei, ...] -} - -#define macro __GWEI() = takes(1) returns(1) { - // expects at least one item on the stack (amount(x) of gwei) - // [x, ...] - [__ONE_GWEI] mul // [x_gwei, ...] -} - -#define macro __ETHER() = takes(1) returns(1) { - // expects at least one item on the stack (amount(x) of ether) - // [x, ...] - [__ONE_ETHER] mul // [x_ether, ...] -} - - - - -// time helpers -#define macro __SECONDS() = takes(1) returns(1) { - // expects at least one item on the stack (amount(x) of seconds) - // [x, ...] - [__ONE_SECONDS] mul // [x_seconds, ...] -} - -#define macro __MINUTES() = takes(1) returns(1) { - // expects at least one item on the stack (amount(x) of minutes) - // [x, ...] - [__ONE_MINUTES] mul // [x_minutes, ...] -} - -#define macro __HOURS() = takes(1) returns(1) { - // expects at least one item on the stack (amount(x) of hours) - // [x, ...] - [__ONE_HOURS] mul // [x_hours, ...] -} - -#define macro __DAYS() = takes(1) returns(1) { - // expects at least one item on the stack (amount(x) of days) - // [x, ...] - [__ONE_DAYS] mul // [x_days, ...] -} - -#define macro __WEEKS() = takes(1) returns(1) { - // expects at least one item on the stack (amount(x) of weeks) - // [x, ...] - [__ONE_WEEKS] mul // [x_weeks, ...] -} \ No newline at end of file diff --git a/src/utils/__TEMP__bnvxrcqsckqdaprqvhayryuhporeghmzSafeTransferLib.huff b/src/utils/__TEMP__bnvxrcqsckqdaprqvhayryuhporeghmzSafeTransferLib.huff deleted file mode 100644 index e62c27e4..00000000 --- a/src/utils/__TEMP__bnvxrcqsckqdaprqvhayryuhporeghmzSafeTransferLib.huff +++ /dev/null @@ -1,202 +0,0 @@ -#define function safeTransferETH(address, uint256) payable returns () -#define function safeTransferFrom(address, address, address, uint256) nonpayable returns () -#define function safeTransfer(address, address, uint256) nonpayable returns () -#define function safeApprove(address, address, uint256) nonpayable returns () - -#define macro SAFE_TRANSFER_ETH_WRAPPER() = { - 0x24 calldataload // [amount] - 0x04 calldataload // [to, amount] - - SAFE_TRANSFER_ETH() - stop -} - -#define macro SAFE_TRANSFER_FROM_WRAPPER() = { - 0x04 calldataload // [token] - 0x64 calldataload // [amount, token] - 0x44 calldataload // [to, amount, token] - 0x24 calldataload // [from, to, amount, token] - - SAFE_TRANSFER_FROM(0x00) - stop -} - -#define macro SAFE_TRANSFER_WRAPPER() = { - 0x04 calldataload // [token] - 0x44 calldataload // [amount, token] - 0x24 calldataload // [to, amount, token] - - SAFE_TRANSFER(0x00) - stop -} - -#define macro SAFE_APPROVE_WRAPPER() = { - 0x04 calldataload // [token] - 0x44 calldataload // [amount, token] - 0x24 calldataload // [to, amount, token] - - SAFE_APPROVE(0x00) - stop -} - -#define macro MAIN() = { - pc calldataload 0xE0 shr - dup1 __FUNC_SIG(safeTransferETH) eq steth jumpi - dup1 __FUNC_SIG(safeTransferFrom) eq stf jumpi - dup1 __FUNC_SIG(safeTransfer) eq st jumpi - dup1 __FUNC_SIG(safeApprove) eq sa jumpi - - 0x00 dup1 revert - - steth: - SAFE_TRANSFER_ETH_WRAPPER() - stf: - SAFE_TRANSFER_FROM_WRAPPER() - st: - SAFE_TRANSFER_WRAPPER() - sa: - SAFE_APPROVE_WRAPPER() -} - - -/// @title SafeTransferLib -/// @notice SPDX-License-Identifier: MIT -/// @notice Safe ETH and ERC20 transfer library that gracefully handles missing return values. -/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/SafeTransferLib.sol) -/// @author Modified from Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/SafeTransferLib.sol) -/// @author clabby -/// @dev Caution! This library won't check that a token has code, responsibility is delegated to the caller. - -/// CONSIDERATION: -/// We could designate byte scratch space for memory -/// which would spare us runtime operations shifting the dynamic memory pointer -/// -/// Designations: -/// - 128 bytes for SAFE_TRANSFER_FROM -/// - 96 bytes for SAFE_TRANSFER -/// - 96 bytes for SAFE_APPROVE - - -/// @notice Safely transfers an `amount` of eth to the address `to` -#define macro SAFE_TRANSFER_ETH() = takes (2) { - // Input stack: [to, amount] - // Output stack: [] - - 0x00 dup1 dup1 dup1 // [0x00, 0x00, 0x00, 0x00, to, amount] - swap5 swap1 swap4 // [to, amount, 0x00, 0x00, 0x00, 0x00] - gas call // [call_success] - success jumpi // [] - - // `ETHTransferFailed()` error - 0xb12d13eb 0x00 mstore - 0x04 0x1c revert - - success: -} - -/// @notice Safely transfers an `amount` of `token` from an address `from` to the address `to` -#define macro SAFE_TRANSFER_FROM(mem_ptr) = takes (4) { - // Input stack: [from, to, value, token] - // Output stack: [] - - __RIGHTPAD(0x23b872dd) // [transferFrom_selector, from, to, amount, token] - // [mem_ptr, transferFrom_selector, from, to, amount, token] - mstore // [from, to, amount, token] - - 0x04 add // [mem_ptr + 0x04, from, to, amount, token] - mstore // [to, amount, token] - 0x24 add // [mem_ptr + 0x24, to, amount, token] - mstore // [amount, token] - 0x44 add // [mem_ptr + 0x44, amount, token] - mstore // [token] - - 0x64 // [0x64, mem_ptr, token] - dup2 0x00 // [0x00, mem_ptr, 0x64, mem_ptr, token] - 0x20 swap5 // [token, 0x00, mem_ptr, 0x64, mem_ptr, 0x20] - gas call // [success] - - returndatasize // [returndatasize, success] - iszero // [returndatasize == 0, success] - // [offset, returndatasize == 0, success] - mload // [data, returndatasize == 0, success] - 0x01 eq // [data == 0x01, returndatasize == 0, success] - or // [data == 0x01 | returndatasize == 0, success] - - and // [success & (data == 0x01 | returndatasize == 0)] - success jumpi // [] - - 0x7939f424 0x00 mstore - 0x04 0x1c revert - - success: -} - -/// @notice Safely transfers an `amount` to an address `to` for the provided `token` -#define macro SAFE_TRANSFER(mem_ptr) = takes (3) { - // Input stack: [to, amount, token] - // Output stack: [] - - __RIGHTPAD(0xa9059cbb) // [transfer_selector, to, amount, token] - // [mem_ptr, transfer_selector, to, amount, token] - mstore // [to, amount, token] - - 0x04 add // [mem_ptr + 0x04, to, amount, token] - mstore // [amount, token] - 0x24 add // [mem_ptr + 0x24, amount, token] - mstore - - 0x44 // [0x44, mem_ptr, token] - dup2 0x00 // [0x00, mem_ptr, 0x44, mem_ptr, token] - 0x20 swap5 // [token, 0x00, mem_ptr, 0x44, mem_ptr, 0x20] - gas call // [success] - - returndatasize // [returndatasize, success] - iszero // [returndatasize == 0, success] - // [offset, returndatasize == 0, success] - mload // [data, returndatasize == 0, success] - 0x01 eq // [data == 0x01, returndatasize == 0, success] - or // [data == 0x01 | returndatasize == 0, success] - - and // [success & (data == 0x01 | returndatasize == 0)] - success jumpi // [] - - 0x90b8ec18 0x00 mstore - 0x04 0x1c revert - - success: -} - -/// @notice Safely approves an `amount` for an address `to` for the provided `token` -#define macro SAFE_APPROVE(mem_ptr) = takes (3) { - // Input stack: [spender, value, token] - // Output stack: [] - - __RIGHTPAD(0x095ea7b3) // [approve_selector, to, amount, token] - // [mem_ptr, approve_selector, to, amount, token] - mstore // [to, amount, token] - - 0x04 add // [mem_ptr + 0x04, to, amount, token] - mstore // [amount, token] - 0x24 add // [mem_ptr + 0x24, amount, token] - mstore - - 0x44 // [0x44, mem_ptr, token] - dup2 0x00 // [0x00, mem_ptr, 0x44, mem_ptr, token] - 0x20 swap5 // [token, 0x00, mem_ptr, 0x44, mem_ptr, 0x20] - gas call // [success] - - returndatasize // [returndatasize, success] - iszero // [returndatasize == 0, success] - // [offset, returndatasize == 0, success] - mload // [data, returndatasize == 0, success] - 0x01 eq // [data == 0x01, returndatasize == 0, success] - or // [data == 0x01 | returndatasize == 0, success] - - and // [success & (data == 0x01 | returndatasize == 0)] - success jumpi // [] - - 0x3e3f8f73 0x00 mstore - 0x04 0x1c revert - - success: -} diff --git a/src/utils/__TEMP__ctwgjphmybkljahoybtnldrrcpneywglECDSA.huff b/src/utils/__TEMP__ctwgjphmybkljahoybtnldrrcpneywglECDSA.huff deleted file mode 100644 index be184d44..00000000 --- a/src/utils/__TEMP__ctwgjphmybkljahoybtnldrrcpneywglECDSA.huff +++ /dev/null @@ -1,305 +0,0 @@ -#define function recoverCd(bytes32, bytes calldata) view returns (address) -#define function recoverShortSig(bytes32, bytes32, bytes32) view returns (address) -#define function recoverVRSSig(bytes32, bytes32, bytes32, bytes32) view returns (address) -#define function toEthSignedMessageHash(bytes32) view returns (bytes32) -#define function toEthSignedMessageHashDyn(bytes) view returns (bytes32) - -#define macro RECOVER_CD_WRAPPER() = { - RECOVER_CD_SIG(0x04, 0x64) // [result] - 0x00 mstore // [] - 0x20 0x00 return -} - -#define macro RECOVER_SHORT_SIG_WRAPPER() = { - 0x04 calldataload // [hash] - 0x24 calldataload // [r, hash] - 0x44 calldataload // [vs, r, hash] - RECOVER_SHORT_SIG() // [result] - 0x00 mstore // [] - 0x20 0x00 return -} - -#define macro RECOVER_VRS_SIG_WRAPPER() = { - 0x64 calldataload // [s] - 0x44 calldataload // [r, s] - 0x24 calldataload // [v, r, s] - 0x04 calldataload // [hash, v, r, s] - RECOVER_VRS_SIG() // [result] - 0x00 mstore // [] - 0x20 0x00 return -} - -#define macro TO_ETH_SIGNED_MSG_HASH_WRAPPER() = { - 0x04 calldataload // [hash] - TO_ETH_SIGNED_MSG_HASH() // [result] - 0x00 mstore // [] - 0x20 0x00 return -} - -#define macro TO_ETH_SIGNED_MSG_HASH_DYN_WRAPPER() = { - 0x24 calldataload // [len(s)] - 0x20 add // [len(s) + 0x20] - 0x24 0x60 calldatacopy // [] - TO_ETH_SIGNED_MSG_HASH_DYN(0x60) // [result] - 0x00 mstore // [] - 0x20 0x00 return -} - -#define macro MAIN() = { - pc calldataload 0xE0 shr - dup1 __FUNC_SIG(recoverCd) eq recover_cd jumpi - dup1 __FUNC_SIG(recoverShortSig) eq recover_short_sig jumpi - dup1 __FUNC_SIG(recoverVRSSig) eq recover_vrs_sig jumpi - dup1 __FUNC_SIG(toEthSignedMessageHash) eq to_eth_signed_msg_hash jumpi - dup1 __FUNC_SIG(toEthSignedMessageHashDyn) eq to_eth_signed_msg_hash_dyn jumpi - - // Revert if no function selectors match - 0x00 dup1 revert - - // Fn dispatch - recover_cd: - RECOVER_CD_WRAPPER() - recover_short_sig: - RECOVER_SHORT_SIG_WRAPPER() - recover_vrs_sig: - RECOVER_VRS_SIG_WRAPPER() - to_eth_signed_msg_hash: - TO_ETH_SIGNED_MSG_HASH_WRAPPER() - to_eth_signed_msg_hash_dyn: - TO_ETH_SIGNED_MSG_HASH_DYN_WRAPPER() -} - - -/// @title ECDSA -/// @notice Gas optimized ECDSA wrapper. -/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/ECDSA.sol) -/// @author Modified from Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/ECDSA.sol) -/// @author Modified from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/cryptography/ECDSA.sol) -/// @author clabby - -//////////////////////////////////////////////////////////////// -// CONSTANTS // -//////////////////////////////////////////////////////////////// - -/// @dev The number which `s` must not exceed in order for the signature to be non-malleable. -#define constant MALLEABILITY_THRESHOLD = 0x7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0 - -/// @dev Ethereum Signed Message header. Used in `TO_ETH_SIGNED_MSG_HASH` -#define constant SIG_HEADER = 0x0000000019457468657265756d205369676e6564204d6573736167653a0a3332 - -/// @dev Ethereum Signed Message header. Used in `TO_ETH_SIGNED_MSG_HASH_DYN` -#define constant SIG_HEADER_DYN = 0x00000000000019457468657265756d205369676e6564204d6573736167653a0a - -//////////////////////////////////////////////////////////////// -// RECOVERY OPERATIONS // -//////////////////////////////////////////////////////////////// - -/// @dev Recovers the signer's address from a message digest `hash`, -/// and the `signature`. -/// -/// This macro does NOT accept EIP-2098 short form signatures. -/// Use `recover(bytes32 hash, bytes32 r, bytes32 vs)` for EIP-2098 -/// short form signatures instead. -/// -/// WARNING! -/// The result will be the zero address upon recovery failure. -/// As such, it is extremely important to ensure that the address which -/// the result is compared against is never zero. -/// @notice The `sig_ptr` param must point to the *offset* of the signature data -/// in calldata. -#define macro RECOVER_CD_SIG(hash_ptr, sig_ptr) = returns (1) { - // Input stack: [] - - calldataload // [hash] - 0x20 sub // [sig_len_ptr, hash] - calldataload // [len(signature), hash] - - // If len(signature) != 65, jump to `zero`. - 0x41 eq iszero // [len(signature) != 0x41, hash] - zero jumpi // [hash] - - // Copy `r` and `s` from the calldata - 0x40 dup2 // [0x40, sig_ptr, 0x40, hash] - calldatacopy // [hash] - - // If `s` is not in lower half order, such that the signature is malleable, - // jump to `zero`. - [MALLEABILITY_THRESHOLD] // [malleability_threshold, hash] - 0x60 mload // [s, malleability_threshold, hash] - gt // [s > MALLEABILITY_THRESHOLD, hash] - zero jumpi // [hash] - - // Store `hash` in scratch space @ 0x00 - 0x00 mstore // [] - // Compute `v` and store it in scratch space @ 0x20 - 0x40 add // [0x40 + sig_ptr] - calldataload // [cd] - 0x00 byte // [v] - 0x20 mstore // [] - - 0x20 0x40 0x80 0x00 0x01 // [0x01, 0x00, 0x80, 0x40, 0x20] - gas staticcall pop // [] - - // Restore the zero slot - 0x00 0x60 mstore // [] - - // `returndatasize` will be `0x20` upon success, and `0x00` otherwise. - returndatasize 0x60 sub // [0x60 - returndatasize] - mload // [result] - end jump // [result] - - zero: - pop 0x00 // [0x00] - end: - - // Return stack: [result] -} - -/// @dev Recovers the signer's address from a message digest `hash`, -/// and the EIP-2098 short form signature defined by `r` and `vs`. -/// -/// This function only accepts EIP-2098 short form signatures. -/// See: https://eips.ethereum.org/EIPS/eip-2098 -/// -/// To be honest, I do not recommend using EIP-2098 signatures -/// for simplicity, performance, and security reasons. Most if not -/// all clients support traditional non EIP-2098 signatures by default. -/// As such, this method is intentionally not fully inlined. -/// It is merely included for completeness. - Vectorized -/// -/// WARNING! -/// The `result` will be the zero address upon recovery failure. -/// As such, it is extremely important to ensure that the address which -/// the `result` is compared against is never zero. -#define macro RECOVER_SHORT_SIG() = takes (3) returns (1) { - // Input stack: [vs, r, hash] - - dup1 0xFF shr 0x1B add // [v, vs, r, hash] - swap1 // [vs, v, r, hash] - 0x01 shl 0x01 shr // [s, v, r, hash] - swap3 // [hash, v, r, s] - RECOVER_VRS_SIG() // [result] - - // Return stack: [result] -} - -/// @dev Recovers the signer's address from a message digest `hash`, -/// and the signature defined by `v`, `r`, `s`. -/// -/// WARNING! -/// The `result` will be the zero address upon recovery failure. -/// As such, it is extremely important to ensure that the address which -/// the `result` is compared against is never zero. -#define macro RECOVER_VRS_SIG() = takes (4) returns (1) { - // Input stack: [hash, v, r, s] - - // If `s` is not in lower half order, such that the signature is malleable, - // jump to `zero`. - [MALLEABILITY_THRESHOLD] // [malleability_threshold, hash, v, r, s] - dup5 gt // [s > malleability_threshold, hash, v, r, s] - zero jumpi // [hash, v, r, s] - - 0x00 mstore // [v, r, s] - 0x20 mstore // [r, s] - 0x40 mstore // [s] - 0x60 mstore // [] - - 0x20 0x40 0x80 0x00 0x01 // [0x01, 0x00, 0x80, 0x40, 0x20] - gas staticcall pop // [] - - // Restore the zero slot - 0x00 0x60 mstore // [] - returndatasize 0x60 sub // [0x60 - returndatasize] - mload // [result] - end jump - - zero: - pop pop pop pop 0x00 // [0x00] - end: - - // Return stack: [result] -} - -/// @dev Returns an Ethereum Signed Message, created from a `hash`. -/// This produces a hash corresponding to the one signed with the -/// [`eth_sign`](https://eth.wiki/json-rpc/API#eth_sign) -/// JSON-RPC method as part of EIP-191. -#define macro TO_ETH_SIGNED_MSG_HASH() = takes (1) returns (1) { - // Input stack: [hash] - - // Store in scratch space for hashing. - 0x20 mstore // [] - [SIG_HEADER] 0x00 mstore // [] - - 0x3c 0x04 sha3 // [result] - - // Return stack: [result] -} -/// @dev Returns an Ethereum Signed Message, created from `s`. -/// This produces a hash corresponding to the one signed with the -/// [`eth_sign`](https://eth.wiki/json-rpc/API#eth_sign) -/// JSON-RPC method as part of EIP-191. -/// -/// @dev The msg *must* be stored at a memory offset >= 0x60. Otherwise, -/// the logic that restores the 128 bytes before the `msg_ptr` will -/// underflow, causing a revert due to excessive memory expansion. -#define macro TO_ETH_SIGNED_MSG_HASH_DYN(msg_ptr) = returns (1) { - // Input stack: [] - - // We need at most 128 bytes for Ethereum signed message header. - // The max length of the ASCII reprenstation of a uint256 is 78 bytes. - // The length of "\x19Ethereum Signed Message:\n" is 26 bytes (i.e. 0x1a). - // The next multiple of 32 above 78 + 26 is 128 (i.e. 0x80). - - // Instead of allocating, we temporarily copy the 128 bytes before the - // start of `msg` data to some variables. - // [msg_ptr] - 0x40 dup2 sub mload // [m2, msg_ptr] - 0x20 dup3 sub mload // [m1, m2, msg_ptr] - 0x60 dup4 sub mload // [m3, m1, m2, msg_ptr] - swap3 // [msg_ptr, m1, m2, m3] - dup1 mload // [len(msg), msg_ptr, m1, m2, m3] - - swap1 0x20 add // [ptr, len(msg), m1, m2, m3] - dup2 dup2 add // [end, ptr, len(msg), m1, m2, m3] - swap1 // [ptr, end, len(msg), m1, m2, m3] - dup3 swap1 // [ptr, temp, end, len(msg), m1, m2, m3] - - loop: - 0x01 swap1 sub // [ptr - 0x01, temp, end, len(msg), m1, m2, m3] - 0x0A dup3 mod // [temp % 0x0A, ptr, temp, end, len(msg), m1, m2, m3] - 0x30 add // [(temp % 0x0A) + 0x30, ptr, temp, end, len(msg), m1, m2, m3] - dup2 mstore8 // [ptr, temp, end, len(msg), m1, m2, m3] - 0x0A dup3 div // [temp / 0x0A, ptr, temp, end, len(msg), m1, m2, m3] - swap2 pop // [ptr, temp, end, len(msg), m1, m2, m3] - - // Continue loop if temp != 0 - dup2 loop jumpi // [ptr, temp, end, len(msg), m1, m2, m3] - - // Copy the header into memory. - [SIG_HEADER_DYN] // [sig_header, ptr, temp, end, len(msg), m1, m2, m3] - 0x20 dup3 sub // [ptr - 0x20, sig_header, ptr, temp, end, len(msg), m1, m2, m3] - mstore // [ptr, temp, end, len(msg), m1, m2, m3] - swap1 pop // [ptr, end, len(msg), m1, m2, m3] - - // Compute the keccak256 hash of the memory. - 0x1A swap1 sub // [ptr - 0x1A, end, len(msg), m1, m2, m3] - dup1 // [ptr - 0x1A, ptr - 0x1A, end, len(msg), m1, m2, m3] - swap2 sub // [end - (ptr - 0x1A), ptr - 0x1A, len(msg), m1, m2, m3] - swap1 // [ptr - 0x1A, end - (ptr - 0x1A), len(msg), m1, m2, m3] - sha3 // [result, len(msg), m1, m2, m3] - - // Restore the previous memory. - // TODO: Can keep msg_ptr on stack here and dup rather than pushing it - // 4 times. - swap4 // [m3, len(msg), m1, m2, result] - 0x60 sub // [sig_ptr - 0x60, m3, len(msg), m1, m2, result] - mstore // [len(msg), m1, m2, result] - mstore // [m1, m2, result] - 0x20 sub // [sig_ptr - 0x20, m1, m2, result] - mstore // [m2, result] - 0x40 sub // [sig_ptr - 0x40, m2, result] - mstore // [result] - - // Return stack: [result] -} diff --git a/src/utils/__TEMP__dabwfcmbyyrjifcrrrqvnmskahrxtfwfPausable.huff b/src/utils/__TEMP__dabwfcmbyyrjifcrrrqvnmskahrxtfwfPausable.huff deleted file mode 100644 index 9a967559..00000000 --- a/src/utils/__TEMP__dabwfcmbyyrjifcrrrqvnmskahrxtfwfPausable.huff +++ /dev/null @@ -1,131 +0,0 @@ -#define function isPaused() view returns (bool) -#define function pause() nonpayable returns () -#define function unpause() nonpayable returns () - - -#define macro CONSTRUCTOR() = takes (0) returns (0) { - PAUSABLE_CONSTRUCTOR() -} - - -#define macro IS_PAUSED_WRAPPER() = takes (0) returns (0) { - PAUSABLE_IS_PAUSED() -} - -#define macro PAUSE_WRAPPER() = takes (0) returns (0) { - PAUSABLE_PAUSE() -} - -#define macro UNPAUSE_WRAPPER() = takes (0) returns (0) { - PAUSABLE_UNPAUSE() -} - - -#define macro MAIN() = takes (0) returns (0) { - pc calldataload 0xe0 shr // [sig] - - dup1 __FUNC_SIG(pause) eq pause jumpi - dup1 __FUNC_SIG(unpause) eq unpause jumpi - dup1 __FUNC_SIG(isPaused) eq is_paused jumpi - - 0x00 dup1 revert - - pause: - PAUSE_WRAPPER() - unpause: - UNPAUSE_WRAPPER() - is_paused: - IS_PAUSED_WRAPPER() -} - -/// @title Pausable -/// @notice SPDX-License-Identifier: MIT -/// @author zarf.eth -/// @notice A Pausable implementation - - -// Interface - -/// @notice returns whether the contract is paused -#define function isPaused() view returns (bool) - -/// @notice Pauses the contract -/// @dev Only callable when the contract is unpaused. -#define function pause() nonpayable returns () - -/// @notice Unpauses the contract -/// @dev Only callable when the contract is paused. -#define function unpause() nonpayable returns () - -/// @notice Emitted when contract is paused. -#define event Paused(address) - -/// @notice Emitted when contract is unpaused. -#define event Unpaused(address) - - -// Storage - -/// @notice Paused Storage Slot -#define constant PAUSED_SLOT = FREE_STORAGE_POINTER() - -/// @notice Unpaused representation -#define constant NOT_PAUSED = 0x01 - -/// @notice Paused representation -#define constant PAUSED = 0x02 - - -/// @notice Pausable constructor -#define macro PAUSABLE_CONSTRUCTOR() = takes (0) returns (0) { - [NOT_PAUSED] [PAUSED_SLOT] sstore // [] -} - -/// @notice whenNotPaused modifier -#define macro WHEN_NOT_PAUSED_MODIFIER() = takes (0) returns (0) { - [PAUSED_SLOT] sload // [isPaused] - [NOT_PAUSED] eq when_not_paused jumpi // [] - 0x00 dup1 revert // [] - when_not_paused: // [] -} - -/// @notice whenPaused modifier -#define macro WHEN_PAUSED_MODIFIER() = takes (0) returns (0) { - [PAUSED_SLOT] sload // [isPaused] - [PAUSED] eq when_paused jumpi // [] - 0x00 dup1 revert // [] - when_paused: // [] -} - -/// @notice return whether contract is paused -#define macro PAUSABLE_IS_PAUSED() = takes (0) returns (0) { - 0x01 // [1] - [PAUSED_SLOT] sload // [isPaused, 1] - sub // [bool] - 0x00 mstore // [] - 0x20 0x00 return // [] -} - -/// @notice Pause the contract -#define macro PAUSABLE_PAUSE() = takes (0) returns (0) { - WHEN_NOT_PAUSED_MODIFIER() // [] - - //emit Paused(address) - caller __EVENT_HASH(Paused) 0x00 dup1 // [0, 0, EVENT_PAUSED, msg.sender] - log2 // [] - - [PAUSED] [PAUSED_SLOT] sstore // [] - stop -} - -/// @notice Unpause the contract -#define macro PAUSABLE_UNPAUSE() = takes (0) returns (0) { - WHEN_PAUSED_MODIFIER() // [] - - //emit Unpaused(address) - caller __EVENT_HASH(Unpaused) 0x00 dup1 // [0, 0, EVENT_UNPAUSED, msg.sender] - log2 // [] - - [NOT_PAUSED] [PAUSED_SLOT] sstore // [] - stop -} diff --git a/src/utils/__TEMP__dolvqpolutctxhctjzvajsrpbtpqfvdlCalls.huff b/src/utils/__TEMP__dolvqpolutctxhctjzvajsrpbtpqfvdlCalls.huff deleted file mode 100644 index 019625c2..00000000 --- a/src/utils/__TEMP__dolvqpolutctxhctjzvajsrpbtpqfvdlCalls.huff +++ /dev/null @@ -1,217 +0,0 @@ - -#define function callFunc() payable returns () -#define function staticcallFunc() payable returns () -#define function callcodeFunc() payable returns () - -#define macro CALL_WRAPPER() = takes (0) returns (0) { - // Store 0xba5ed in memory - 0xba5ed dup1 0x00 mstore // [0xba5ed] - - // Static Call - CALL(0x01, 0x00, 0x01, 0x00, 0x00, 0x04, 0xFFFFFFFF) // [success, 0xba5ed] - - // Revert if call is unsuccessful - iszero iszero cont jumpi - 0x00 dup1 revert - cont: - - // Load the result - 0x00 mload // [res, 0xba5ed] - - // Compare the results and revert if unequal - eq success jumpi // [] - 0x00 dup1 revert - success: - - stop -} - -#define macro STATICCALL_WRAPPER() = takes (0) returns (0) { - // Store 0xba5ed in memory - 0xba5ed dup1 0x00 mstore // [0xba5ed] - - // Static Call - STATICCALL(0x01, 0x00, 0x01, 0x00, 0x04, 0xFFFFFFFF) // [success, 0xba5ed] - - // Revert if call is unsuccessful - iszero iszero cont jumpi - 0x00 dup1 revert - cont: - - // Load the result - 0x00 mload // [res, 0xba5ed] - - // Compare the results and revert if unequal - eq success jumpi // [] - 0x00 dup1 revert - success: - - stop -} - -#define macro CALLCODE_WRAPPER() = takes (0) returns (0) { - // TODO - - stop -} - -#define macro MAIN() = takes (0) returns (0) { - // Load the function selector - pc calldataload 0xE0 shr // [sig] - - // Match on the function selector - dup1 __FUNC_SIG(callFunc) eq call_jump jumpi // [sig] - dup1 __FUNC_SIG(staticcallFunc) eq staticcall_jump jumpi // [sig] - dup1 __FUNC_SIG(callcodeFunc) eq callcode_jump jumpi // [sig] - - 0x00 dup1 revert - - call_jump: - CALL_WRAPPER() - staticcall_jump: - STATICCALL_WRAPPER() - callcode_jump: - CALLCODE_WRAPPER() -} - - -/// @title Calls -/// @notice SPDX-License-Identifier: MIT -/// @author asnared -/// @author Franfran -/// @notice Calls is a library of utility functions for calling contracts - -/// @notice Calls a contract with the given arguments -/// @notice Returns the success of the call -/// @notice Returndata is left in memory for the caller to handle -/// @param ret_size The size of the return data -/// @param ret_offset The offset in memory to store the return data -/// @param arg_size The size of the arguments -/// @param arg_offset The offset in memory of the arguments -/// @param value The value to send with the call -/// @param to The address to call -/// @param gas The amount of gas to send with the call -#define macro CALL( - ret_size, - ret_offset, - arg_size, - arg_offset, - value, - to, - maxgas -) = takes (0) returns (1) { - // [retSize] - // [retOffset, retSize] - // [argSize, retOffset, retSize] - // [argOffset, argSize, retOffset, retSize] - // [value, argOffset, argSize, retOffset, retSize] - // [to, value, argOffset, argSize, retOffset, retSize] - // [gas, to, value, argOffset, argSize, retOffset, retSize] - call // [success] -} - -/// @notice Staticalls a contract with the given arguments -/// @notice Returns the success of the call -/// @notice Returndata is left in memory for the caller to handle -/// @dev This instructions is equivalent to CALL, except that it does not allow any state modifying instructions or sending ETH in the sub context. -/// @dev The disallowed instructions are CREATE, CREATE2, LOG0, LOG1, LOG2, LOG3, LOG4, SSTORE, SELFDESTRUCT and CALL if the value sent is not 0. -/// @dev If the size of the return data is not known, it can also be retrieved after the call with the instructions RETURNDATASIZE and RETURNDATACOPY (since the Byzantium fork). -/// @param ret_size The size of the return data -/// @param ret_offset The offset in memory to store the return data -/// @param arg_size The size of the arguments -/// @param arg_offset The offset in memory of the arguments -/// @param to The address to call -/// @param gas The amount of gas to send with the call -#define macro STATICCALL( - ret_size, - ret_offset, - arg_size, - arg_offset, - to, - maxgas -) = takes (0) returns (1) { - // [retSize] - // [retOffset, retSize] - // [argSize, retOffset, retSize] - // [argOffset, argSize, retOffset, retSize] - // [to, argOffset, argSize, retOffset, retSize] - // [gas, to, argOffset, argSize, retOffset, retSize] - staticcall // [success] -} - -/// @notice Codecalls a contract with the given arguments -/// @notice Returns the success of the call -/// @notice Returndata is left in memory for the caller to handle -/// @dev Creates a new sub context as if calling itself, but with the code of the given account. -/// @dev In particular the storage remains the same. Note that an account with no code will return success as true. -/// @dev If the size of the return data is not known, it can also be retrieved after the call with the instructions RETURNDATASIZE and RETURNDATACOPY (since the Byzantium fork). -/// @param ret_size The size of the return data -/// @param ret_offset The offset in memory to store the return data -/// @param arg_size The size of the arguments -/// @param arg_offset The offset in memory of the arguments -/// @param value The value to send with the call -/// @param to The address to call -/// @param gas The amount of gas to send with the call -#define macro CALLCODE( - ret_size, - ret_offset, - arg_size, - arg_offset, - value, - to, - maxgas -) = takes (0) returns (1) { - // [retSize] - // [retOffset, retSize] - // [argSize, retOffset, retSize] - // [argOffset, argSize, retOffset, retSize] - // [value, argOffset, argSize, retOffset, retSize] - // [to, argOffset, argSize, retOffset, retSize] - // [gas, to, argOffset, argSize, retOffset, retSize] - callcode // [success] -} - -/// @notice Test call the identity precompile -#define test TEST_CALL() = takes (0) returns (0) { - // Store 0xba5ed in memory - 0xba5ed dup1 0x00 mstore // [0xba5ed] - - // Static Call - CALL(0x01, 0x00, 0x01, 0x00, 0x00, 0x04, 0xFFFFFFFF) // [success, 0xba5ed] - - // Revert if call is unsuccessful - iszero iszero cont jumpi - 0x00 dup1 revert - cont: - - // Load the result - 0x00 mload // [res, 0xba5ed] - - // Compare the results and revert if unequal - eq success jumpi // [] - 0x00 dup1 revert - success: -} - -/// @notice Test staticcall the identity precompile -#define test TEST_STATIC_CALL() = takes (0) returns (0) { - // Store 0xba5ed in memory - 0xba5ed dup1 0x00 mstore // [0xba5ed] - - // Static Call - STATICCALL(0x01, 0x00, 0x01, 0x00, 0x04, 0xFFFFFFFF) // [success, 0xba5ed] - - // Revert if call is unsuccessful - iszero iszero cont jumpi - 0x00 dup1 revert - cont: - - // Load the result - 0x00 mload // [res, 0xba5ed] - - // Compare the results and revert if unequal - eq success jumpi // [] - 0x00 dup1 revert - success: -} - diff --git a/src/utils/__TEMP__ejbyrnbkhzztmedggubevwdmphskibtxMerkleDistributor.huff b/src/utils/__TEMP__ejbyrnbkhzztmedggubevwdmphskibtxMerkleDistributor.huff deleted file mode 100644 index 867e8160..00000000 --- a/src/utils/__TEMP__ejbyrnbkhzztmedggubevwdmphskibtxMerkleDistributor.huff +++ /dev/null @@ -1,247 +0,0 @@ - -#define macro CONSTRUCTOR() = takes (0) returns (0) { - MERKLE_DISTRIBUTOR_CONSTRUCTOR() -} - -#define macro MAIN() = takes (0) returns (0) { - pc calldataload 0xE0 shr - MERKLE_DISTRIBUTOR_MAIN() - 0x00 dup1 revert -} - - -/// @title Merkle Distributor -/// @notice SPDX-License-Identifier: MIT -/// @author Ben Leimberger -/// @author Magna -/// @author asnared -/// @notice Minimal, gas efficient Merkle Distributor implementation - - -// Imports -#include "./CommonErrors.huff" -#include "./MerkleProofLib.huff" -#include "./Address.huff" -#include "./ERC20Transfer.huff" - -// Interface -#define function claim(uint256,address,uint256,bytes32[]) nonpayable returns () - -#define function getMerkleRoot() view returns (bytes32) -#define function getTokenAddress() view returns (address) -#define function isClaimed(uint256) view returns (bool) - -// Storage Slots -#define constant CLAIMED_BIT_MAP_SLOT = FREE_STORAGE_POINTER() // 0x00 -#define constant TOKEN_ADDR_SLOT = FREE_STORAGE_POINTER() // 0x01 -#define constant MERKLE_ROOT_SLOT = FREE_STORAGE_POINTER() // 0x02 - -// Errors -#define error TransferError(string) -#define error ClaimedError(string) -#define error ProofError(string) - - -/// @notice Get Merkle Root -/// @notice Entry point for: getMerkleRoot() -/// @dev Fetches merkle root from storage slot -/// @param {calldata} [] -/// @return {return} [bytes32 root] -#define macro GET_MERKLE_ROOT() = takes (0) returns (0) { - // Load value from storage - [MERKLE_ROOT_SLOT] sload // [merkle_root] - - // Store value in memory - 0x00 mstore // [] - - // Return value - 0x20 0x00 return // [] -} - -/// @notice Get Token Address -#define macro GET_TOKEN_ADDR() = takes (0) returns (0) { - // Load value from storage - [TOKEN_ADDR_SLOT] sload // [token_addr] - - // Store value in memory - 0x00 mstore // [] - - // Return value - 0x20 0x00 return // [] -} - - -/// Is Claimed -/// @notice Entry point for: isClaimed(uint256) -/// @dev Check if index is claimed -/// @param {calldata} [uint256 index] -/// @return {return} [bytes32 root] -#define macro IS_CLAIMED() = takes (0) returns (0) { - // Load first argument from calldata - 0x04 calldataload // [index] - - // Utility macro - __UTIL_IS_CLAIMED() // [isEqual] - - // store result in memory - 0x00 mstore // [] - 0x20 0x00 return -} - -/// @dev stores result in 0x00 to 0x20 memory slot -#define macro __UTIL_IS_CLAIMED() = takes (1) returns (1) { - // Stack input: // [arg0] - // Stack output: // [isEqual] - // index / 256 - 0x100 dup2 div // [index] - - __UTIL_GENERATE_MAPPING_KEY() // [key(claimed[index]), arg0] - - // Load mapping key - sload // [claimed[index], arg0] - - // index % 256 [claimed[index], arg0] - 0x1 0x100 dup4 mod shl // [mask, claimed[index], arg0] - dup1 swap2 dup2 and // [masked, mask, claimed[index], arg0] - eq // [isEqual, claimed[index], arg0] - swap2 pop pop // [isEqual] -} - - -/// @notice Set as claimed -#define macro __UTIL_SET_CLAIMED() = takes (1) returns (0) { - // Stack input: // [arg0] - - // index / 256 - 0x100 dup2 div // [index, arg0] - - __UTIL_GENERATE_MAPPING_KEY() // [key(claimed[index]), arg0] - - // Load mapping key - dup1 sload // [claimed[index], key(claimed[index]), arg0] - - // index % 256 [claimed[index], key(claimed[index]), arg0] - 0x1 0x100 dup5 mod shl // [mask, claimed[index], key(claimed[index]), arg0] - or // [masked, key(claimed[to]), arg0] - - // Update - swap1 sstore pop // [] -} - -/// @notice Creates a mapping key from an index -#define macro __UTIL_GENERATE_MAPPING_KEY() = takes (1) returns (1) { - // Stack input: [index] - // Stack output: [key(claimed[index])] - 0x00 mstore // [] - [CLAIMED_BIT_MAP_SLOT] 0x20 mstore // [] - - // key(claimed[index]) = keccak256(index . claimedBitMapSlot) - 0x40 0x00 sha3 // [key(claimed[index])] -} - -/// @notice Claim -/// @notice Entry point for: claim(uint256,address,uint256,bytes[]) -/// @dev Claim distribution with proof -/// @param {calldata} [uint256 index, address account, uint256 amount, bytes[] proof] -/// @return {return} [] -#define macro CLAIM() = takes (0) returns (0) { - // Preload merkle root - [MERKLE_ROOT_SLOT] sload // [root] - - // Load arguments from calldata - 0x44 calldataload // [amount, root] - 0x24 calldataload MASK_ADDRESS() // [account, amount, root] - 0x04 calldataload // [index, account, amount, root] - - // Check if an index is claimed - dup1 __UTIL_IS_CLAIMED() // [isClaimed, index, account, amount, root] - iszero cont jumpi // [index, account, amount, root] - ALREADY_CLAIMED(0x00) - cont: - - // EncodePacked - // [ 32 bytes | 20 bytes | 32 bytes ] = 84 bytes - 0x00 mstore // [account, amount, root] - 0x60 shl // [account << 12, amount, root] - 0x20 mstore // [amount, root] - 0x34 mstore // [root] - 0x54 0x00 sha3 // [leaf, root] - - // Verify merkle proof - 0x64 calldataload 0x4 add // [&proof_length, leaf, root] - - // Required() - VERIFY_PROOF() // [isProven] - verified jumpi // [] - INVALID_PROOF(0x00) - verified: - - // Mark it claimed - 0x04 calldataload // [arg0] - __UTIL_SET_CLAIMED() // [] - - // Load other calldata arguments - [TOKEN_ADDR_SLOT] sload // [getter_addr] - 0x44 calldataload // [amount, getter_addr] - 0x24 calldataload // [address_raw, amount, getter_addr] - MASK_ADDRESS() // [address, amount, getter_addr] - - // Send the token - ERC20_TRANSFER() - - // Finish Execution - stop -} - -/// @notice Constructor -/// @param address The address of the token to distribute -/// @param merkleRoot The merkle root of the merkle tree -#define macro MERKLE_DISTRIBUTOR_CONSTRUCTOR() = takes (0) returns (0) { - // Copy the first argument into memory - 0x20 // [size] - byte size to copy - 0x40 codesize sub // [offset, size] - offset in the code to copy from - 0x00 // [mem, offset, size] - offset in memory to copy to - codecopy // [] - - // Store the first argument in storage - 0x00 mload // [arg1] - [TOKEN_ADDR_SLOT] // [TOKEN_ADDR, arg1] - sstore // [] - - // Copy the second argument into memory - 0x20 // [size] - byte size to copy - 0x20 codesize sub // [offset, size] - offset in the code to copy from - 0x00 // [mem, offset, size] - offset in memory to copy to - codecopy // [] - - // Store the second argument in storage - 0x00 mload // [arg2] - [MERKLE_ROOT_SLOT] // [CONSTRUCTOR_ARG_TWO, arg2] - sstore // [] -} - -/// @notice Function Dispatch -/// @notice Takes the first 4 bytes of calldata (aka the function selector) and dispatches to the appropriate function -/// @notice If non match, execution proceeds as the code is inlined -#define macro MERKLE_DISTRIBUTOR_MAIN() = takes (1) returns (1) { - // Input Stack: [function_selector] - - dup1 __FUNC_SIG(getTokenAddress) eq getTokenAddress jumpi - dup1 __FUNC_SIG(getMerkleRoot) eq getMerkleRoot jumpi - dup1 __FUNC_SIG(isClaimed) eq isClaimed jumpi - dup1 __FUNC_SIG(claim) eq claim jumpi - - // Jump to the end if non match - no_match jump - - getMerkleRoot: - GET_MERKLE_ROOT() - getTokenAddress: - GET_TOKEN_ADDR() - isClaimed: - IS_CLAIMED() - claim: - CLAIM() - - no_match: -} \ No newline at end of file diff --git a/src/utils/__TEMP__epqcrijckuxiernloalienlasrtffackConstants.huff b/src/utils/__TEMP__epqcrijckuxiernloalienlasrtffackConstants.huff deleted file mode 100644 index 157180e7..00000000 --- a/src/utils/__TEMP__epqcrijckuxiernloalienlasrtffackConstants.huff +++ /dev/null @@ -1,1789 +0,0 @@ - -// interface -#define function oneWei() pure returns(uint256) -#define function oneGwei() pure returns(uint256) -#define function oneEther() pure returns(uint256) -#define function oneSeconds() pure returns(uint256) -#define function oneMinutes() pure returns(uint256) -#define function oneHours() pure returns(uint256) -#define function oneDays() pure returns(uint256) -#define function oneWeeks() pure returns(uint256) - -#define function uint256Max() pure returns(uint256) -#define function uint248Max() pure returns(uint256) -#define function uint240Max() pure returns(uint256) -#define function uint232Max() pure returns(uint256) -#define function uint224Max() pure returns(uint256) -#define function uint216Max() pure returns(uint256) -#define function uint208Max() pure returns(uint256) -#define function uint200Max() pure returns(uint256) -#define function uint192Max() pure returns(uint256) -#define function uint184Max() pure returns(uint256) -#define function uint176Max() pure returns(uint256) -#define function uint168Max() pure returns(uint256) -#define function uint160Max() pure returns(uint256) -#define function uint152Max() pure returns(uint256) -#define function uint144Max() pure returns(uint256) -#define function uint136Max() pure returns(uint256) -#define function uint128Max() pure returns(uint256) -#define function uint120Max() pure returns(uint256) -#define function uint112Max() pure returns(uint256) -#define function uint104Max() pure returns(uint256) -#define function uint96Max() pure returns(uint256) -#define function uint88Max() pure returns(uint256) -#define function uint80Max() pure returns(uint256) -#define function uint72Max() pure returns(uint256) -#define function uint64Max() pure returns(uint256) -#define function uint56Max() pure returns(uint256) -#define function uint48Max() pure returns(uint256) -#define function uint40Max() pure returns(uint256) -#define function uint32Max() pure returns(uint256) -#define function uint24Max() pure returns(uint256) -#define function uint16Max() pure returns(uint256) -#define function uint8Max() pure returns(uint256) - -#define function int256Max() pure returns(int256) -#define function int248Max() pure returns(int256) -#define function int240Max() pure returns(int256) -#define function int232Max() pure returns(int256) -#define function int224Max() pure returns(int256) -#define function int216Max() pure returns(int256) -#define function int208Max() pure returns(int256) -#define function int200Max() pure returns(int256) -#define function int192Max() pure returns(int256) -#define function int184Max() pure returns(int256) -#define function int176Max() pure returns(int256) -#define function int168Max() pure returns(int256) -#define function int160Max() pure returns(int256) -#define function int152Max() pure returns(int256) -#define function int144Max() pure returns(int256) -#define function int136Max() pure returns(int256) -#define function int128Max() pure returns(int256) -#define function int120Max() pure returns(int256) -#define function int112Max() pure returns(int256) -#define function int104Max() pure returns(int256) -#define function int96Max() pure returns(int256) -#define function int88Max() pure returns(int256) -#define function int80Max() pure returns(int256) -#define function int72Max() pure returns(int256) -#define function int64Max() pure returns(int256) -#define function int56Max() pure returns(int256) -#define function int48Max() pure returns(int256) -#define function int40Max() pure returns(int256) -#define function int32Max() pure returns(int256) -#define function int24Max() pure returns(int256) -#define function int16Max() pure returns(int256) -#define function int8Max() pure returns(int256) - -#define function int256Min() pure returns(int256) -#define function int248Min() pure returns(int256) -#define function int240Min() pure returns(int256) -#define function int232Min() pure returns(int256) -#define function int224Min() pure returns(int256) -#define function int216Min() pure returns(int256) -#define function int208Min() pure returns(int256) -#define function int200Min() pure returns(int256) -#define function int192Min() pure returns(int256) -#define function int184Min() pure returns(int256) -#define function int176Min() pure returns(int256) -#define function int168Min() pure returns(int256) -#define function int160Min() pure returns(int256) -#define function int152Min() pure returns(int256) -#define function int144Min() pure returns(int256) -#define function int136Min() pure returns(int256) -#define function int128Min() pure returns(int256) -#define function int120Min() pure returns(int256) -#define function int112Min() pure returns(int256) -#define function int104Min() pure returns(int256) -#define function int96Min() pure returns(int256) -#define function int88Min() pure returns(int256) -#define function int80Min() pure returns(int256) -#define function int72Min() pure returns(int256) -#define function int64Min() pure returns(int256) -#define function int56Min() pure returns(int256) -#define function int48Min() pure returns(int256) -#define function int40Min() pure returns(int256) -#define function int32Min() pure returns(int256) -#define function int24Min() pure returns(int256) -#define function int16Min() pure returns(int256) -#define function int8Min() pure returns(int256) - -#define function multiWei(uint256) pure returns(uint256) -#define function multiGwei(uint256) pure returns(uint256) -#define function multiEther(uint256) pure returns(uint256) -#define function multiSeconds(uint256) pure returns(uint256) -#define function multiMinutes(uint256) pure returns(uint256) -#define function multiHours(uint256) pure returns(uint256) -#define function multiDays(uint256) pure returns(uint256) -#define function multiWeeks(uint256) pure returns(uint256) - - -#define macro ONE_WEI() = takes(0) returns(0) { - [__ONE_WEI] 0x00 mstore - 0x20 0x00 return -} - -#define macro ONE_GWEI() = takes(0) returns(0) { - [__ONE_GWEI] 0x00 mstore - 0x20 0x00 return -} - -#define macro ONE_ETHER() = takes(0) returns(0) { - [__ONE_ETHER] 0x00 mstore - 0x20 0x00 return -} - -#define macro ONE_SECONDS() = takes(0) returns(0) { - [__ONE_SECONDS] 0x00 mstore - 0x20 0x00 return -} - -#define macro ONE_MINUTES() = takes(0) returns(0) { - [__ONE_MINUTES] 0x00 mstore - 0x20 0x00 return -} - -#define macro ONE_HOURS() = takes(0) returns(0) { - [__ONE_HOURS] 0x00 mstore - 0x20 0x00 return -} - -#define macro ONE_DAYS() = takes(0) returns(0) { - [__ONE_DAYS] 0x00 mstore - 0x20 0x00 return -} - -#define macro ONE_WEEKS() = takes(0) returns(0) { - [__ONE_WEEKS] 0x00 mstore - 0x20 0x00 return -} - - - -#define macro UINT256_MAX() = takes(0) returns(0) { - [__UINT256_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro UINT248_MAX() = takes(0) returns(0) { - [__UINT248_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro UINT240_MAX() = takes(0) returns(0) { - [__UINT240_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro UINT232_MAX() = takes(0) returns(0) { - [__UINT232_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro UINT224_MAX() = takes(0) returns(0) { - [__UINT224_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro UINT216_MAX() = takes(0) returns(0) { - [__UINT216_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro UINT208_MAX() = takes(0) returns(0) { - [__UINT208_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro UINT200_MAX() = takes(0) returns(0) { - [__UINT200_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro UINT192_MAX() = takes(0) returns(0) { - [__UINT192_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro UINT184_MAX() = takes(0) returns(0) { - [__UINT184_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro UINT176_MAX() = takes(0) returns(0) { - [__UINT176_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro UINT168_MAX() = takes(0) returns(0) { - [__UINT168_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro UINT160_MAX() = takes(0) returns(0) { - [__UINT160_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro UINT152_MAX() = takes(0) returns(0) { - [__UINT152_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro UINT144_MAX() = takes(0) returns(0) { - [__UINT144_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro UINT136_MAX() = takes(0) returns(0) { - [__UINT136_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro UINT128_MAX() = takes(0) returns(0) { - [__UINT128_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro UINT120_MAX() = takes(0) returns(0) { - [__UINT120_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro UINT112_MAX() = takes(0) returns(0) { - [__UINT112_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro UINT104_MAX() = takes(0) returns(0) { - [__UINT104_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro UINT96_MAX() = takes(0) returns(0) { - [__UINT96_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro UINT88_MAX() = takes(0) returns(0) { - [__UINT88_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro UINT80_MAX() = takes(0) returns(0) { - [__UINT80_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro UINT72_MAX() = takes(0) returns(0) { - [__UINT72_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro UINT64_MAX() = takes(0) returns(0) { - [__UINT64_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro UINT56_MAX() = takes(0) returns(0) { - [__UINT56_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro UINT48_MAX() = takes(0) returns(0) { - [__UINT48_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro UINT40_MAX() = takes(0) returns(0) { - [__UINT40_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro UINT32_MAX() = takes(0) returns(0) { - [__UINT32_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro UINT24_MAX() = takes(0) returns(0) { - [__UINT24_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro UINT16_MAX() = takes(0) returns(0) { - [__UINT16_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro UINT8_MAX() = takes(0) returns(0) { - [__UINT8_MAX] 0x00 mstore - 0x20 0x00 return -} - - - - - - -#define macro INT256_MAX() = takes(0) returns(0) { - [__INT256_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT248_MAX() = takes(0) returns(0) { - [__INT248_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT240_MAX() = takes(0) returns(0) { - [__INT240_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT232_MAX() = takes(0) returns(0) { - [__INT232_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT224_MAX() = takes(0) returns(0) { - [__INT224_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT216_MAX() = takes(0) returns(0) { - [__INT216_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT208_MAX() = takes(0) returns(0) { - [__INT208_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT200_MAX() = takes(0) returns(0) { - [__INT200_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT192_MAX() = takes(0) returns(0) { - [__INT192_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT184_MAX() = takes(0) returns(0) { - [__INT184_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT176_MAX() = takes(0) returns(0) { - [__INT176_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT168_MAX() = takes(0) returns(0) { - [__INT168_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT160_MAX() = takes(0) returns(0) { - [__INT160_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT152_MAX() = takes(0) returns(0) { - [__INT152_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT144_MAX() = takes(0) returns(0) { - [__INT144_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT136_MAX() = takes(0) returns(0) { - [__INT136_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT128_MAX() = takes(0) returns(0) { - [__INT128_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT120_MAX() = takes(0) returns(0) { - [__INT120_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT112_MAX() = takes(0) returns(0) { - [__INT112_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT104_MAX() = takes(0) returns(0) { - [__INT104_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT96_MAX() = takes(0) returns(0) { - [__INT96_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT88_MAX() = takes(0) returns(0) { - [__INT88_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT80_MAX() = takes(0) returns(0) { - [__INT80_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT72_MAX() = takes(0) returns(0) { - [__INT72_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT64_MAX() = takes(0) returns(0) { - [__INT64_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT56_MAX() = takes(0) returns(0) { - [__INT56_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT48_MAX() = takes(0) returns(0) { - [__INT48_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT40_MAX() = takes(0) returns(0) { - [__INT40_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT32_MAX() = takes(0) returns(0) { - [__INT32_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT24_MAX() = takes(0) returns(0) { - [__INT24_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT16_MAX() = takes(0) returns(0) { - [__INT16_MAX] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT8_MAX() = takes(0) returns(0) { - [__INT8_MAX] 0x00 mstore - 0x20 0x00 return -} - - - - - - -#define macro INT256_MIN() = takes(0) returns(0) { - [__INT256_MIN] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT248_MIN() = takes(0) returns(0) { - [__INT248_MIN] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT240_MIN() = takes(0) returns(0) { - [__INT240_MIN] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT232_MIN() = takes(0) returns(0) { - [__INT232_MIN] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT224_MIN() = takes(0) returns(0) { - [__INT224_MIN] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT216_MIN() = takes(0) returns(0) { - [__INT216_MIN] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT208_MIN() = takes(0) returns(0) { - [__INT208_MIN] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT200_MIN() = takes(0) returns(0) { - [__INT200_MIN] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT192_MIN() = takes(0) returns(0) { - [__INT192_MIN] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT184_MIN() = takes(0) returns(0) { - [__INT184_MIN] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT176_MIN() = takes(0) returns(0) { - [__INT176_MIN] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT168_MIN() = takes(0) returns(0) { - [__INT168_MIN] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT160_MIN() = takes(0) returns(0) { - [__INT160_MIN] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT152_MIN() = takes(0) returns(0) { - [__INT152_MIN] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT144_MIN() = takes(0) returns(0) { - [__INT144_MIN] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT136_MIN() = takes(0) returns(0) { - [__INT136_MIN] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT128_MIN() = takes(0) returns(0) { - [__INT128_MIN] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT120_MIN() = takes(0) returns(0) { - [__INT120_MIN] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT112_MIN() = takes(0) returns(0) { - [__INT112_MIN] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT104_MIN() = takes(0) returns(0) { - [__INT104_MIN] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT96_MIN() = takes(0) returns(0) { - [__INT96_MIN] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT88_MIN() = takes(0) returns(0) { - [__INT88_MIN] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT80_MIN() = takes(0) returns(0) { - [__INT80_MIN] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT72_MIN() = takes(0) returns(0) { - [__INT72_MIN] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT64_MIN() = takes(0) returns(0) { - [__INT64_MIN] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT56_MIN() = takes(0) returns(0) { - [__INT56_MIN] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT48_MIN() = takes(0) returns(0) { - [__INT48_MIN] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT40_MIN() = takes(0) returns(0) { - [__INT40_MIN] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT32_MIN() = takes(0) returns(0) { - [__INT32_MIN] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT24_MIN() = takes(0) returns(0) { - [__INT24_MIN] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT16_MIN() = takes(0) returns(0) { - [__INT16_MIN] 0x00 mstore - 0x20 0x00 return -} - -#define macro INT8_MIN() = takes(0) returns(0) { - [__INT8_MIN] 0x00 mstore - 0x20 0x00 return -} - - - - -#define macro MULTI_WEI() = takes(0) returns(0) { - 0x04 calldataload __WEI() 0x00 mstore - 0x20 0x00 return -} - -#define macro MULTI_GWEI() = takes(0) returns(0) { - 0x04 calldataload __GWEI() 0x00 mstore - 0x20 0x00 return -} - -#define macro MULTI_ETHER() = takes(0) returns(0) { - 0x04 calldataload __ETHER() 0x00 mstore - 0x20 0x00 return -} - -#define macro MULTI_SECONDS() = takes(0) returns(0) { - 0x04 calldataload __SECONDS() 0x00 mstore - 0x20 0x00 return -} - -#define macro MULTI_MINUTES() = takes(0) returns(0) { - 0x04 calldataload __MINUTES() 0x00 mstore - 0x20 0x00 return -} - -#define macro MULTI_HOURS() = takes(0) returns(0) { - 0x04 calldataload __HOURS() 0x00 mstore - 0x20 0x00 return -} - -#define macro MULTI_DAYS() = takes(0) returns(0) { - 0x04 calldataload __DAYS() 0x00 mstore - 0x20 0x00 return -} - -#define macro MULTI_WEEKS() = takes(0) returns(0) { - 0x04 calldataload __WEEKS() 0x00 mstore - 0x20 0x00 return -} - - - - - - - - - -// Function Dispatching -#define macro MAIN() = takes (1) returns (1) { - // Identify which function is being called. - // [func sig] - 0x00 calldataload 0xE0 shr - - - // function int104Max() pure returns (int256) - dup1 __FUNC_SIG(int104Max) eq int104MaxJump jumpi - - - // function int104Min() pure returns (int256) - dup1 __FUNC_SIG(int104Min) eq int104MinJump jumpi - - - // function int112Max() pure returns (int256) - dup1 __FUNC_SIG(int112Max) eq int112MaxJump jumpi - - - // function int112Min() pure returns (int256) - dup1 __FUNC_SIG(int112Min) eq int112MinJump jumpi - - - // function int120Max() pure returns (int256) - dup1 __FUNC_SIG(int120Max) eq int120MaxJump jumpi - - - // function int120Min() pure returns (int256) - dup1 __FUNC_SIG(int120Min) eq int120MinJump jumpi - - - // function int128Max() pure returns (int256) - dup1 __FUNC_SIG(int128Max) eq int128MaxJump jumpi - - - // function int128Min() pure returns (int256) - dup1 __FUNC_SIG(int128Min) eq int128MinJump jumpi - - - // function int136Max() pure returns (int256) - dup1 __FUNC_SIG(int136Max) eq int136MaxJump jumpi - - - // function int136Min() pure returns (int256) - dup1 __FUNC_SIG(int136Min) eq int136MinJump jumpi - - - // function int144Max() pure returns (int256) - dup1 __FUNC_SIG(int144Max) eq int144MaxJump jumpi - - - // function int144Min() pure returns (int256) - dup1 __FUNC_SIG(int144Min) eq int144MinJump jumpi - - - // function int152Max() pure returns (int256) - dup1 __FUNC_SIG(int152Max) eq int152MaxJump jumpi - - - // function int152Min() pure returns (int256) - dup1 __FUNC_SIG(int152Min) eq int152MinJump jumpi - - - // function int160Max() pure returns (int256) - dup1 __FUNC_SIG(int160Max) eq int160MaxJump jumpi - - - // function int160Min() pure returns (int256) - dup1 __FUNC_SIG(int160Min) eq int160MinJump jumpi - - - // function int168Max() pure returns (int256) - dup1 __FUNC_SIG(int168Max) eq int168MaxJump jumpi - - - // function int168Min() pure returns (int256) - dup1 __FUNC_SIG(int168Min) eq int168MinJump jumpi - - - // function int16Max() pure returns (int256) - dup1 __FUNC_SIG(int16Max) eq int16MaxJump jumpi - - - // function int16Min() pure returns (int256) - dup1 __FUNC_SIG(int16Min) eq int16MinJump jumpi - - - // function int176Max() pure returns (int256) - dup1 __FUNC_SIG(int176Max) eq int176MaxJump jumpi - - - // function int176Min() pure returns (int256) - dup1 __FUNC_SIG(int176Min) eq int176MinJump jumpi - - - // function int184Max() pure returns (int256) - dup1 __FUNC_SIG(int184Max) eq int184MaxJump jumpi - - - // function int184Min() pure returns (int256) - dup1 __FUNC_SIG(int184Min) eq int184MinJump jumpi - - - // function int192Max() pure returns (int256) - dup1 __FUNC_SIG(int192Max) eq int192MaxJump jumpi - - - // function int192Min() pure returns (int256) - dup1 __FUNC_SIG(int192Min) eq int192MinJump jumpi - - - // function int200Max() pure returns (int256) - dup1 __FUNC_SIG(int200Max) eq int200MaxJump jumpi - - - // function int200Min() pure returns (int256) - dup1 __FUNC_SIG(int200Min) eq int200MinJump jumpi - - - // function int208Max() pure returns (int256) - dup1 __FUNC_SIG(int208Max) eq int208MaxJump jumpi - - - // function int208Min() pure returns (int256) - dup1 __FUNC_SIG(int208Min) eq int208MinJump jumpi - - - // function int216Max() pure returns (int256) - dup1 __FUNC_SIG(int216Max) eq int216MaxJump jumpi - - - // function int216Min() pure returns (int256) - dup1 __FUNC_SIG(int216Min) eq int216MinJump jumpi - - - // function int224Max() pure returns (int256) - dup1 __FUNC_SIG(int224Max) eq int224MaxJump jumpi - - - // function int224Min() pure returns (int256) - dup1 __FUNC_SIG(int224Min) eq int224MinJump jumpi - - - // function int232Max() pure returns (int256) - dup1 __FUNC_SIG(int232Max) eq int232MaxJump jumpi - - - // function int232Min() pure returns (int256) - dup1 __FUNC_SIG(int232Min) eq int232MinJump jumpi - - - // function int240Max() pure returns (int256) - dup1 __FUNC_SIG(int240Max) eq int240MaxJump jumpi - - - // function int240Min() pure returns (int256) - dup1 __FUNC_SIG(int240Min) eq int240MinJump jumpi - - - // function int248Max() pure returns (int256) - dup1 __FUNC_SIG(int248Max) eq int248MaxJump jumpi - - - // function int248Min() pure returns (int256) - dup1 __FUNC_SIG(int248Min) eq int248MinJump jumpi - - - // function int24Max() pure returns (int256) - dup1 __FUNC_SIG(int24Max) eq int24MaxJump jumpi - - - // function int24Min() pure returns (int256) - dup1 __FUNC_SIG(int24Min) eq int24MinJump jumpi - - - // function int256Max() pure returns (int256) - dup1 __FUNC_SIG(int256Max) eq int256MaxJump jumpi - - - // function int256Min() pure returns (int256) - dup1 __FUNC_SIG(int256Min) eq int256MinJump jumpi - - - // function int32Max() pure returns (int256) - dup1 __FUNC_SIG(int32Max) eq int32MaxJump jumpi - - - // function int32Min() pure returns (int256) - dup1 __FUNC_SIG(int32Min) eq int32MinJump jumpi - - - // function int40Max() pure returns (int256) - dup1 __FUNC_SIG(int40Max) eq int40MaxJump jumpi - - - // function int40Min() pure returns (int256) - dup1 __FUNC_SIG(int40Min) eq int40MinJump jumpi - - - // function int48Max() pure returns (int256) - dup1 __FUNC_SIG(int48Max) eq int48MaxJump jumpi - - - // function int48Min() pure returns (int256) - dup1 __FUNC_SIG(int48Min) eq int48MinJump jumpi - - - // function int56Max() pure returns (int256) - dup1 __FUNC_SIG(int56Max) eq int56MaxJump jumpi - - - // function int56Min() pure returns (int256) - dup1 __FUNC_SIG(int56Min) eq int56MinJump jumpi - - - // function int64Max() pure returns (int256) - dup1 __FUNC_SIG(int64Max) eq int64MaxJump jumpi - - - // function int64Min() pure returns (int256) - dup1 __FUNC_SIG(int64Min) eq int64MinJump jumpi - - - // function int72Max() pure returns (int256) - dup1 __FUNC_SIG(int72Max) eq int72MaxJump jumpi - - - // function int72Min() pure returns (int256) - dup1 __FUNC_SIG(int72Min) eq int72MinJump jumpi - - - // function int80Max() pure returns (int256) - dup1 __FUNC_SIG(int80Max) eq int80MaxJump jumpi - - - // function int80Min() pure returns (int256) - dup1 __FUNC_SIG(int80Min) eq int80MinJump jumpi - - - // function int88Max() pure returns (int256) - dup1 __FUNC_SIG(int88Max) eq int88MaxJump jumpi - - - // function int88Min() pure returns (int256) - dup1 __FUNC_SIG(int88Min) eq int88MinJump jumpi - - - // function int8Max() pure returns (int256) - dup1 __FUNC_SIG(int8Max) eq int8MaxJump jumpi - - - // function int8Min() pure returns (int256) - dup1 __FUNC_SIG(int8Min) eq int8MinJump jumpi - - - // function int96Max() pure returns (int256) - dup1 __FUNC_SIG(int96Max) eq int96MaxJump jumpi - - - // function int96Min() pure returns (int256) - dup1 __FUNC_SIG(int96Min) eq int96MinJump jumpi - - - // function multiDays(uint256) pure returns (uint256) - dup1 __FUNC_SIG(multiDays) eq multiDaysJump jumpi - - - // function multiEther(uint256) pure returns (uint256) - dup1 __FUNC_SIG(multiEther) eq multiEtherJump jumpi - - - // function multiGwei(uint256) pure returns (uint256) - dup1 __FUNC_SIG(multiGwei) eq multiGweiJump jumpi - - - // function multiHours(uint256) pure returns (uint256) - dup1 __FUNC_SIG(multiHours) eq multiHoursJump jumpi - - - // function multiMinutes(uint256) pure returns (uint256) - dup1 __FUNC_SIG(multiMinutes) eq multiMinutesJump jumpi - - - // function multiSeconds(uint256) pure returns (uint256) - dup1 __FUNC_SIG(multiSeconds) eq multiSecondsJump jumpi - - - // function multiWeeks(uint256) pure returns (uint256) - dup1 __FUNC_SIG(multiWeeks) eq multiWeeksJump jumpi - - - // function multiWei(uint256) pure returns (uint256) - dup1 __FUNC_SIG(multiWei) eq multiWeiJump jumpi - - - // function oneDays() pure returns (uint256) - dup1 __FUNC_SIG(oneDays) eq oneDaysJump jumpi - - - // function oneEther() pure returns (uint256) - dup1 __FUNC_SIG(oneEther) eq oneEtherJump jumpi - - - // function oneGwei() pure returns (uint256) - dup1 __FUNC_SIG(oneGwei) eq oneGweiJump jumpi - - - // function oneHours() pure returns (uint256) - dup1 __FUNC_SIG(oneHours) eq oneHoursJump jumpi - - - // function oneMinutes() pure returns (uint256) - dup1 __FUNC_SIG(oneMinutes) eq oneMinutesJump jumpi - - - // function oneSeconds() pure returns (uint256) - dup1 __FUNC_SIG(oneSeconds) eq oneSecondsJump jumpi - - - // function oneWeeks() pure returns (uint256) - dup1 __FUNC_SIG(oneWeeks) eq oneWeeksJump jumpi - - - // function oneWei() pure returns (uint256) - dup1 __FUNC_SIG(oneWei) eq oneWeiJump jumpi - - - // function uint104Max() pure returns (uint256) - dup1 __FUNC_SIG(uint104Max) eq uint104MaxJump jumpi - - - // function uint112Max() pure returns (uint256) - dup1 __FUNC_SIG(uint112Max) eq uint112MaxJump jumpi - - - // function uint120Max() pure returns (uint256) - dup1 __FUNC_SIG(uint120Max) eq uint120MaxJump jumpi - - - // function uint128Max() pure returns (uint256) - dup1 __FUNC_SIG(uint128Max) eq uint128MaxJump jumpi - - - // function uint136Max() pure returns (uint256) - dup1 __FUNC_SIG(uint136Max) eq uint136MaxJump jumpi - - - // function uint144Max() pure returns (uint256) - dup1 __FUNC_SIG(uint144Max) eq uint144MaxJump jumpi - - - // function uint152Max() pure returns (uint256) - dup1 __FUNC_SIG(uint152Max) eq uint152MaxJump jumpi - - - // function uint160Max() pure returns (uint256) - dup1 __FUNC_SIG(uint160Max) eq uint160MaxJump jumpi - - - // function uint168Max() pure returns (uint256) - dup1 __FUNC_SIG(uint168Max) eq uint168MaxJump jumpi - - - // function uint16Max() pure returns (uint256) - dup1 __FUNC_SIG(uint16Max) eq uint16MaxJump jumpi - - - // function uint176Max() pure returns (uint256) - dup1 __FUNC_SIG(uint176Max) eq uint176MaxJump jumpi - - - // function uint184Max() pure returns (uint256) - dup1 __FUNC_SIG(uint184Max) eq uint184MaxJump jumpi - - - // function uint192Max() pure returns (uint256) - dup1 __FUNC_SIG(uint192Max) eq uint192MaxJump jumpi - - - // function uint200Max() pure returns (uint256) - dup1 __FUNC_SIG(uint200Max) eq uint200MaxJump jumpi - - - // function uint208Max() pure returns (uint256) - dup1 __FUNC_SIG(uint208Max) eq uint208MaxJump jumpi - - - // function uint216Max() pure returns (uint256) - dup1 __FUNC_SIG(uint216Max) eq uint216MaxJump jumpi - - - // function uint224Max() pure returns (uint256) - dup1 __FUNC_SIG(uint224Max) eq uint224MaxJump jumpi - - - // function uint232Max() pure returns (uint256) - dup1 __FUNC_SIG(uint232Max) eq uint232MaxJump jumpi - - - // function uint240Max() pure returns (uint256) - dup1 __FUNC_SIG(uint240Max) eq uint240MaxJump jumpi - - - // function uint248Max() pure returns (uint256) - dup1 __FUNC_SIG(uint248Max) eq uint248MaxJump jumpi - - - // function uint24Max() pure returns (uint256) - dup1 __FUNC_SIG(uint24Max) eq uint24MaxJump jumpi - - - // function uint256Max() pure returns (uint256) - dup1 __FUNC_SIG(uint256Max) eq uint256MaxJump jumpi - - - // function uint32Max() pure returns (uint256) - dup1 __FUNC_SIG(uint32Max) eq uint32MaxJump jumpi - - - // function uint40Max() pure returns (uint256) - dup1 __FUNC_SIG(uint40Max) eq uint40MaxJump jumpi - - - // function uint48Max() pure returns (uint256) - dup1 __FUNC_SIG(uint48Max) eq uint48MaxJump jumpi - - - // function uint56Max() pure returns (uint256) - dup1 __FUNC_SIG(uint56Max) eq uint56MaxJump jumpi - - - // function uint64Max() pure returns (uint256) - dup1 __FUNC_SIG(uint64Max) eq uint64MaxJump jumpi - - - // function uint72Max() pure returns (uint256) - dup1 __FUNC_SIG(uint72Max) eq uint72MaxJump jumpi - - - // function uint80Max() pure returns (uint256) - dup1 __FUNC_SIG(uint80Max) eq uint80MaxJump jumpi - - - // function uint88Max() pure returns (uint256) - dup1 __FUNC_SIG(uint88Max) eq uint88MaxJump jumpi - - - // function uint8Max() pure returns (uint256) - dup1 __FUNC_SIG(uint8Max) eq uint8MaxJump jumpi - - - // function uint96Max() pure returns (uint256) - dup1 __FUNC_SIG(uint96Max) eq uint96MaxJump jumpi - - not_found: - // Revert if no match is found. - 0x00 dup1 revert - - - // function uint168Max() pure returns (uint256) - uint168MaxJump: - UINT168_MAX() - - // function int184Max() pure returns (int256) - int184MaxJump: - INT184_MAX() - - // function int40Max() pure returns (int256) - int40MaxJump: - INT40_MAX() - - // function oneWeeks() pure returns (uint256) - oneWeeksJump: - ONE_WEEKS() - - // function uint160Max() pure returns (uint256) - uint160MaxJump: - UINT160_MAX() - - // function int176Min() pure returns (int256) - int176MinJump: - INT176_MIN() - - // function int88Max() pure returns (int256) - int88MaxJump: - INT88_MAX() - - // function int168Min() pure returns (int256) - int168MinJump: - INT168_MIN() - - // function int208Min() pure returns (int256) - int208MinJump: - INT208_MIN() - - // function uint104Max() pure returns (uint256) - uint104MaxJump: - UINT104_MAX() - - // function int24Min() pure returns (int256) - int24MinJump: - INT24_MIN() - - // function int112Min() pure returns (int256) - int112MinJump: - INT112_MIN() - - // function int96Max() pure returns (int256) - int96MaxJump: - INT96_MAX() - - // function int96Min() pure returns (int256) - int96MinJump: - INT96_MIN() - - // function uint128Max() pure returns (uint256) - uint128MaxJump: - UINT128_MAX() - - // function uint200Max() pure returns (uint256) - uint200MaxJump: - UINT200_MAX() - - // function oneHours() pure returns (uint256) - oneHoursJump: - ONE_HOURS() - - // function int144Min() pure returns (int256) - int144MinJump: - INT144_MIN() - - // function uint24Max() pure returns (uint256) - uint24MaxJump: - UINT24_MAX() - - // function uint120Max() pure returns (uint256) - uint120MaxJump: - UINT120_MAX() - - // function int256Max() pure returns (int256) - int256MaxJump: - INT256_MAX() - - // function int136Max() pure returns (int256) - int136MaxJump: - INT136_MAX() - - // function int216Max() pure returns (int256) - int216MaxJump: - INT216_MAX() - - // function int144Max() pure returns (int256) - int144MaxJump: - INT144_MAX() - - // function int72Min() pure returns (int256) - int72MinJump: - INT72_MIN() - - // function oneWei() pure returns (uint256) - oneWeiJump: - ONE_WEI() - - // function multiDays(uint256) pure returns (uint256) - multiDaysJump: - MULTI_DAYS() - - // function int64Min() pure returns (int256) - int64MinJump: - INT64_MIN() - - // function uint248Max() pure returns (uint256) - uint248MaxJump: - UINT248_MAX() - - // function int24Max() pure returns (int256) - int24MaxJump: - INT24_MAX() - - // function uint176Max() pure returns (uint256) - uint176MaxJump: - UINT176_MAX() - - // function int32Max() pure returns (int256) - int32MaxJump: - INT32_MAX() - - // function int232Max() pure returns (int256) - int232MaxJump: - INT232_MAX() - - // function int48Min() pure returns (int256) - int48MinJump: - INT48_MIN() - - // function multiSeconds(uint256) pure returns (uint256) - multiSecondsJump: - MULTI_SECONDS() - - // function int224Min() pure returns (int256) - int224MinJump: - INT224_MIN() - - // function int216Min() pure returns (int256) - int216MinJump: - INT216_MIN() - - // function int88Min() pure returns (int256) - int88MinJump: - INT88_MIN() - - // function uint136Max() pure returns (uint256) - uint136MaxJump: - UINT136_MAX() - - // function int248Min() pure returns (int256) - int248MinJump: - INT248_MIN() - - // function int176Max() pure returns (int256) - int176MaxJump: - INT176_MAX() - - // function uint8Max() pure returns (uint256) - uint8MaxJump: - UINT8_MAX() - - // function int56Max() pure returns (int256) - int56MaxJump: - INT56_MAX() - - // function int80Min() pure returns (int256) - int80MinJump: - INT80_MIN() - - // function int200Min() pure returns (int256) - int200MinJump: - INT200_MIN() - - // function uint48Max() pure returns (uint256) - uint48MaxJump: - UINT48_MAX() - - // function int192Max() pure returns (int256) - int192MaxJump: - INT192_MAX() - - // function int208Max() pure returns (int256) - int208MaxJump: - INT208_MAX() - - // function int40Min() pure returns (int256) - int40MinJump: - INT40_MIN() - - // function int192Min() pure returns (int256) - int192MinJump: - INT192_MIN() - - // function int64Max() pure returns (int256) - int64MaxJump: - INT64_MAX() - - // function multiHours(uint256) pure returns (uint256) - multiHoursJump: - MULTI_HOURS() - - // function int16Max() pure returns (int256) - int16MaxJump: - INT16_MAX() - - // function multiEther(uint256) pure returns (uint256) - multiEtherJump: - MULTI_ETHER() - - // function uint64Max() pure returns (uint256) - uint64MaxJump: - UINT64_MAX() - - // function uint216Max() pure returns (uint256) - uint216MaxJump: - UINT216_MAX() - - // function int248Max() pure returns (int256) - int248MaxJump: - INT248_MAX() - - // function int184Min() pure returns (int256) - int184MinJump: - INT184_MIN() - - // function oneGwei() pure returns (uint256) - oneGweiJump: - ONE_GWEI() - - // function int136Min() pure returns (int256) - int136MinJump: - INT136_MIN() - - // function int104Min() pure returns (int256) - int104MinJump: - INT104_MIN() - - // function uint40Max() pure returns (uint256) - uint40MaxJump: - UINT40_MAX() - - // function uint96Max() pure returns (uint256) - uint96MaxJump: - UINT96_MAX() - - // function multiMinutes(uint256) pure returns (uint256) - multiMinutesJump: - MULTI_MINUTES() - - // function uint72Max() pure returns (uint256) - uint72MaxJump: - UINT72_MAX() - - // function int56Min() pure returns (int256) - int56MinJump: - INT56_MIN() - - // function multiGwei(uint256) pure returns (uint256) - multiGweiJump: - MULTI_GWEI() - - // function int232Min() pure returns (int256) - int232MinJump: - INT232_MIN() - - // function uint224Max() pure returns (uint256) - uint224MaxJump: - UINT224_MAX() - - // function uint80Max() pure returns (uint256) - uint80MaxJump: - UINT80_MAX() - - // function int16Min() pure returns (int256) - int16MinJump: - INT16_MIN() - - // function int120Max() pure returns (int256) - int120MaxJump: - INT120_MAX() - - // function uint152Max() pure returns (uint256) - uint152MaxJump: - UINT152_MAX() - - // function multiWei(uint256) pure returns (uint256) - multiWeiJump: - MULTI_WEI() - - // function int200Max() pure returns (int256) - int200MaxJump: - INT200_MAX() - - // function uint144Max() pure returns (uint256) - uint144MaxJump: - UINT144_MAX() - - // function uint32Max() pure returns (uint256) - uint32MaxJump: - UINT32_MAX() - - // function uint184Max() pure returns (uint256) - uint184MaxJump: - UINT184_MAX() - - // function int128Min() pure returns (int256) - int128MinJump: - INT128_MIN() - - // function uint16Max() pure returns (uint256) - uint16MaxJump: - UINT16_MAX() - - // function int160Max() pure returns (int256) - int160MaxJump: - INT160_MAX() - - // function uint208Max() pure returns (uint256) - uint208MaxJump: - UINT208_MAX() - - // function int168Max() pure returns (int256) - int168MaxJump: - INT168_MAX() - - // function oneDays() pure returns (uint256) - oneDaysJump: - ONE_DAYS() - - // function oneMinutes() pure returns (uint256) - oneMinutesJump: - ONE_MINUTES() - - // function int120Min() pure returns (int256) - int120MinJump: - INT120_MIN() - - // function oneSeconds() pure returns (uint256) - oneSecondsJump: - ONE_SECONDS() - - // function int8Max() pure returns (int256) - int8MaxJump: - INT8_MAX() - - // function uint112Max() pure returns (uint256) - uint112MaxJump: - UINT112_MAX() - - // function int8Min() pure returns (int256) - int8MinJump: - INT8_MIN() - - // function oneEther() pure returns (uint256) - oneEtherJump: - ONE_ETHER() - - // function int72Max() pure returns (int256) - int72MaxJump: - INT72_MAX() - - // function int240Max() pure returns (int256) - int240MaxJump: - INT240_MAX() - - // function multiWeeks(uint256) pure returns (uint256) - multiWeeksJump: - MULTI_WEEKS() - - // function int32Min() pure returns (int256) - int32MinJump: - INT32_MIN() - - // function int80Max() pure returns (int256) - int80MaxJump: - INT80_MAX() - - // function int160Min() pure returns (int256) - int160MinJump: - INT160_MIN() - - // function uint256Max() pure returns (uint256) - uint256MaxJump: - UINT256_MAX() - - // function uint240Max() pure returns (uint256) - uint240MaxJump: - UINT240_MAX() - - // function uint192Max() pure returns (uint256) - uint192MaxJump: - UINT192_MAX() - - // function int112Max() pure returns (int256) - int112MaxJump: - INT112_MAX() - - // function uint56Max() pure returns (uint256) - uint56MaxJump: - UINT56_MAX() - - // function int256Min() pure returns (int256) - int256MinJump: - INT256_MIN() - - // function int48Max() pure returns (int256) - int48MaxJump: - INT48_MAX() - - // function int224Max() pure returns (int256) - int224MaxJump: - INT224_MAX() - - // function int128Max() pure returns (int256) - int128MaxJump: - INT128_MAX() - - // function int152Max() pure returns (int256) - int152MaxJump: - INT152_MAX() - - // function int240Min() pure returns (int256) - int240MinJump: - INT240_MIN() - - // function uint232Max() pure returns (uint256) - uint232MaxJump: - UINT232_MAX() - - // function int104Max() pure returns (int256) - int104MaxJump: - INT104_MAX() - - // function uint88Max() pure returns (uint256) - uint88MaxJump: - UINT88_MAX() - - // function int152Min() pure returns (int256) - int152MinJump: - INT152_MIN() -} - -/// @title Constants -/// @notice SPDX-License-Identifier: MIT -/// @author AmadiMichael -/// @notice common constants found in solidity and helpers in huff - - -// value constants -#define constant __ONE_WEI = 0x01 -#define constant __ONE_GWEI = 0x3b9aca00 -#define constant __ONE_ETHER = 0xde0b6b3a7640000 - - -// time constants -#define constant __ONE_SECONDS = 0x01 -#define constant __ONE_MINUTES = 0x3c -#define constant __ONE_HOURS = 0xe10 -#define constant __ONE_DAYS = 0x15180 -#define constant __ONE_WEEKS = 0x93a80 - - -// type ranges constants -#define constant __UINT256_MAX = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -#define constant __UINT248_MAX = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -#define constant __UINT240_MAX = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -#define constant __UINT232_MAX = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -#define constant __UINT224_MAX = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffff -#define constant __UINT216_MAX = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffff -#define constant __UINT208_MAX = 0xffffffffffffffffffffffffffffffffffffffffffffffffffff -#define constant __UINT200_MAX = 0xffffffffffffffffffffffffffffffffffffffffffffffffff -#define constant __UINT192_MAX = 0xffffffffffffffffffffffffffffffffffffffffffffffff -#define constant __UINT184_MAX = 0xffffffffffffffffffffffffffffffffffffffffffffff -#define constant __UINT176_MAX = 0xffffffffffffffffffffffffffffffffffffffffffff -#define constant __UINT168_MAX = 0xffffffffffffffffffffffffffffffffffffffffff -#define constant __UINT160_MAX = 0xffffffffffffffffffffffffffffffffffffffff -#define constant __UINT152_MAX = 0xffffffffffffffffffffffffffffffffffffff -#define constant __UINT144_MAX = 0xffffffffffffffffffffffffffffffffffff -#define constant __UINT136_MAX = 0xffffffffffffffffffffffffffffffffff -#define constant __UINT128_MAX = 0xffffffffffffffffffffffffffffffff -#define constant __UINT120_MAX = 0xffffffffffffffffffffffffffffff -#define constant __UINT112_MAX = 0xffffffffffffffffffffffffffff -#define constant __UINT104_MAX = 0xffffffffffffffffffffffffff -#define constant __UINT96_MAX = 0xffffffffffffffffffffffff -#define constant __UINT88_MAX = 0xffffffffffffffffffffff -#define constant __UINT80_MAX = 0xffffffffffffffffffff -#define constant __UINT72_MAX = 0xffffffffffffffffff -#define constant __UINT64_MAX = 0xffffffffffffffff -#define constant __UINT56_MAX = 0xffffffffffffff -#define constant __UINT48_MAX = 0xffffffffffff -#define constant __UINT40_MAX = 0xffffffffff -#define constant __UINT32_MAX = 0xffffffff -#define constant __UINT24_MAX = 0xffffff -#define constant __UINT16_MAX = 0xffff -#define constant __UINT8_MAX = 0xff - - -#define constant __INT256_MAX = 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -#define constant __INT248_MAX = 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -#define constant __INT240_MAX = 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -#define constant __INT232_MAX = 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffff -#define constant __INT224_MAX = 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffff -#define constant __INT216_MAX = 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffff -#define constant __INT208_MAX = 0x7fffffffffffffffffffffffffffffffffffffffffffffffffff -#define constant __INT200_MAX = 0x7fffffffffffffffffffffffffffffffffffffffffffffffff -#define constant __INT192_MAX = 0x7fffffffffffffffffffffffffffffffffffffffffffffff -#define constant __INT184_MAX = 0x7fffffffffffffffffffffffffffffffffffffffffffff -#define constant __INT176_MAX = 0x7fffffffffffffffffffffffffffffffffffffffffff -#define constant __INT168_MAX = 0x7fffffffffffffffffffffffffffffffffffffffff -#define constant __INT160_MAX = 0x7fffffffffffffffffffffffffffffffffffffff -#define constant __INT152_MAX = 0x7fffffffffffffffffffffffffffffffffffff -#define constant __INT144_MAX = 0x7fffffffffffffffffffffffffffffffffff -#define constant __INT136_MAX = 0x7fffffffffffffffffffffffffffffffff -#define constant __INT128_MAX = 0x7fffffffffffffffffffffffffffffff -#define constant __INT120_MAX = 0x7fffffffffffffffffffffffffffff -#define constant __INT112_MAX = 0x7fffffffffffffffffffffffffff -#define constant __INT104_MAX = 0x7fffffffffffffffffffffffff -#define constant __INT96_MAX = 0x7fffffffffffffffffffffff -#define constant __INT88_MAX = 0x7fffffffffffffffffffff -#define constant __INT80_MAX = 0x7fffffffffffffffffff -#define constant __INT72_MAX = 0x7fffffffffffffffff -#define constant __INT64_MAX = 0x7fffffffffffffff -#define constant __INT56_MAX = 0x7fffffffffffff -#define constant __INT48_MAX = 0x7fffffffffff -#define constant __INT40_MAX = 0x7fffffffff -#define constant __INT32_MAX = 0x7fffffff -#define constant __INT24_MAX = 0x7fffff -#define constant __INT16_MAX = 0x7fff -#define constant __INT8_MAX = 0x7f - -#define constant __INT256_MIN = 0x8000000000000000000000000000000000000000000000000000000000000000 -#define constant __INT248_MIN = 0xff80000000000000000000000000000000000000000000000000000000000000 -#define constant __INT240_MIN = 0xffff800000000000000000000000000000000000000000000000000000000000 -#define constant __INT232_MIN = 0xffffff8000000000000000000000000000000000000000000000000000000000 -#define constant __INT224_MIN = 0xffffffff80000000000000000000000000000000000000000000000000000000 -#define constant __INT216_MIN = 0xffffffffff800000000000000000000000000000000000000000000000000000 -#define constant __INT208_MIN = 0xffffffffffff8000000000000000000000000000000000000000000000000000 -#define constant __INT200_MIN = 0xffffffffffffff80000000000000000000000000000000000000000000000000 -#define constant __INT192_MIN = 0xffffffffffffffff800000000000000000000000000000000000000000000000 -#define constant __INT184_MIN = 0xffffffffffffffffff8000000000000000000000000000000000000000000000 -#define constant __INT176_MIN = 0xffffffffffffffffffff80000000000000000000000000000000000000000000 -#define constant __INT168_MIN = 0xffffffffffffffffffffff800000000000000000000000000000000000000000 -#define constant __INT160_MIN = 0xffffffffffffffffffffffff8000000000000000000000000000000000000000 -#define constant __INT152_MIN = 0xffffffffffffffffffffffffff80000000000000000000000000000000000000 -#define constant __INT144_MIN = 0xffffffffffffffffffffffffffff800000000000000000000000000000000000 -#define constant __INT136_MIN = 0xffffffffffffffffffffffffffffff8000000000000000000000000000000000 -#define constant __INT128_MIN = 0xffffffffffffffffffffffffffffffff80000000000000000000000000000000 -#define constant __INT120_MIN = 0xffffffffffffffffffffffffffffffffff800000000000000000000000000000 -#define constant __INT112_MIN = 0xffffffffffffffffffffffffffffffffffff8000000000000000000000000000 -#define constant __INT104_MIN = 0xffffffffffffffffffffffffffffffffffffff80000000000000000000000000 -#define constant __INT96_MIN = 0xffffffffffffffffffffffffffffffffffffffff800000000000000000000000 -#define constant __INT88_MIN = 0xffffffffffffffffffffffffffffffffffffffffff8000000000000000000000 -#define constant __INT80_MIN = 0xffffffffffffffffffffffffffffffffffffffffffff80000000000000000000 -#define constant __INT72_MIN = 0xffffffffffffffffffffffffffffffffffffffffffffff800000000000000000 -#define constant __INT64_MIN = 0xffffffffffffffffffffffffffffffffffffffffffffffff8000000000000000 -#define constant __INT56_MIN = 0xffffffffffffffffffffffffffffffffffffffffffffffffff80000000000000 -#define constant __INT48_MIN = 0xffffffffffffffffffffffffffffffffffffffffffffffffffff800000000000 -#define constant __INT40_MIN = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffff8000000000 -#define constant __INT32_MIN = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffff80000000 -#define constant __INT24_MIN = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffff800000 -#define constant __INT16_MIN = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8000 -#define constant __INT8_MIN = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80 - - - -// value helpers -// if you don't mind an extra 8 gas then these helper functions can be "helpful" - - -#define macro __WEI() = takes(1) returns(1) { - // expects at least one item on the stack (amount(x) of wei) - // [x, ...] - [__ONE_WEI] mul // [x_wei, ...] -} - -#define macro __GWEI() = takes(1) returns(1) { - // expects at least one item on the stack (amount(x) of gwei) - // [x, ...] - [__ONE_GWEI] mul // [x_gwei, ...] -} - -#define macro __ETHER() = takes(1) returns(1) { - // expects at least one item on the stack (amount(x) of ether) - // [x, ...] - [__ONE_ETHER] mul // [x_ether, ...] -} - - - - -// time helpers -#define macro __SECONDS() = takes(1) returns(1) { - // expects at least one item on the stack (amount(x) of seconds) - // [x, ...] - [__ONE_SECONDS] mul // [x_seconds, ...] -} - -#define macro __MINUTES() = takes(1) returns(1) { - // expects at least one item on the stack (amount(x) of minutes) - // [x, ...] - [__ONE_MINUTES] mul // [x_minutes, ...] -} - -#define macro __HOURS() = takes(1) returns(1) { - // expects at least one item on the stack (amount(x) of hours) - // [x, ...] - [__ONE_HOURS] mul // [x_hours, ...] -} - -#define macro __DAYS() = takes(1) returns(1) { - // expects at least one item on the stack (amount(x) of days) - // [x, ...] - [__ONE_DAYS] mul // [x_days, ...] -} - -#define macro __WEEKS() = takes(1) returns(1) { - // expects at least one item on the stack (amount(x) of weeks) - // [x, ...] - [__ONE_WEEKS] mul // [x_weeks, ...] -} \ No newline at end of file diff --git a/src/utils/__TEMP__eyomwxkixnogyzbecekrqolgmjnwpgibLibBit.huff b/src/utils/__TEMP__eyomwxkixnogyzbecekrqolgmjnwpgibLibBit.huff deleted file mode 100644 index 2ee77790..00000000 --- a/src/utils/__TEMP__eyomwxkixnogyzbecekrqolgmjnwpgibLibBit.huff +++ /dev/null @@ -1,267 +0,0 @@ -#define function fls(uint256) pure returns (uint256) -#define function ffs(uint256) pure returns (uint256) -#define function popCount(uint256) pure returns (uint256) -#define function isPowOf2(uint256) pure returns (uint256) - -#define macro FLS_WRAPPER() = { - 0x04 calldataload - FLS() - - 0x00 mstore - 0x20 0x00 return -} - -#define macro FFS_WRAPPER() = { - 0x04 calldataload - FFS() - - 0x00 mstore - 0x20 0x00 return -} - -#define macro POP_COUNT_WRAPPER() = { - 0x04 calldataload - POP_COUNT() - - 0x00 mstore - 0x20 0x00 return -} - -#define macro IS_POW_OF_2_WRAPPER() = { - 0x04 calldataload - IS_POW_OF_2() - - 0x00 mstore - 0x20 0x00 return -} - -#define macro MAIN() = { - pc calldataload 0xE0 shr - dup1 __FUNC_SIG(fls) eq fls jumpi - dup1 __FUNC_SIG(ffs) eq ffs jumpi - dup1 __FUNC_SIG(popCount) eq pop_count jumpi - dup1 __FUNC_SIG(isPowOf2) eq is_pow_of_2 jumpi - - 0x00 dup1 revert - - fls: - FLS_WRAPPER() - ffs: - FFS_WRAPPER() - pop_count: - POP_COUNT_WRAPPER() - is_pow_of_2: - IS_POW_OF_2_WRAPPER() -} - - -/// @title LibBit -/// @notice SPDX-License-Identifier: MIT -/// @author Vectorized -/// @author Solady (https://github.com/Vectorized/solady/blob/main/src/utils/LibBit.sol) -/// @author Inspired by (https://graphics.stanford.edu/~seander/bithacks.html) -/// @author clabby -/// @notice Various bit-twiddling macros. - -#define constant A = 0xffffffffffffffffffffffffffffffff -#define constant B = 0xffffffffffffffff -#define constant C = 0xffffffff - -#define constant FLS_DEBRUIJN = 0x0009010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f -#define constant FFS_DEBRUIJN = 0x00011c021d0e18031e16140f191104081f1b0d17151310071a0c12060b050a09 - -/// @dev Returns the index of the most significant bit of `x`. -/// If `x` is zero, returns 256. -#define macro FLS() = takes (1) returns (1) { - // Input stack: [x] - - dup1 iszero // [x == 0, x] - 0x08 shl // [(x == 0) << 0x08, x] - - dup2 [A] lt // [A < x, r, x] - 0x07 shl // [(A < x) << 0x07, r, x] - or // [r, x] - - dup2 dup2 shr // [x >> r, r, x] - [B] lt // [B < (x >> r), r, x] - 0x06 shl // [(B < (x >> r)) << 0x06, r, x] - or // [r, x] - - dup2 dup2 shr // [x >> r, r, x] - [C] lt // [C < (x >> r), r, x] - 0x05 shl // [(C < (x >> r)) << 0x05, r, x] - or // [r, x] - - // For the remaining 32 bits, use a De Bruijn lookup. - swap1 dup2 shr // [x >> r, r] - dup1 0x01 shr // [(x >> r) >> 0x01, x >> r, r] - or // [x, r] - - dup1 0x02 shr // [x >> 0x02, x, r] - or // [x, r] - - dup1 0x04 shr // [x >> 0x04, x, r] - or // [x, r] - - dup1 0x08 shr // [x >> 0x08, x, r] - or // [x, r] - - dup1 0x10 shr // [x >> 0x10, r] - or // [x, r] - - // Note: This does increase final code size, can shift left by 224 at runtime - // if codesize is more of a concern. - __RIGHTPAD(0x07c4acdd) // [0x07c4acdd (right padded), x, r] - mul // [x * 0x07c4acdd, r] - 0xFB shr // [(x * 0x07c4acdd) >> 0xFB, r] - [FLS_DEBRUIJN] swap1 // [(x * 0x07c4acdd) >> 0xFB, debruijn_lookup, r] - byte // [b, r] - or // [b | r] - - // Return stack: [r] -} - -/// @dev Returns the index of the least significant bit of `x`. -/// If `x` is zero, returns 256. -#define macro FFS() = takes (1) returns (1) { - // Input stack: [x] - - dup1 iszero // [x == 0, x] - 0x08 shl // [(x == 0) << 0x08, x] - - // Isolate the least significant bit. - swap1 dup1 // [x, x, r] - not 0x01 add // [~x + 1, x, r] - and // [x, r] - - swap1 dup2 // [x, r, x] - [A] lt // [A < x, r, x] - 0x07 shl // [(A < x) << 0x07, r, x] - or // [r, x] - - dup2 dup2 shr // [x >> r, r, x] - [B] lt // [B < (x >> r), r, x] - 0x06 shl // [(B < (x >> r)) << 0x06, r, x] - or // [r, x] - - dup2 dup2 shr // [x >> r, r, x] - [C] lt // [C < (x >> r), r, x] - 0x05 shl // [(C < (x >> r)) << 0x05] - or // [r, x] - - // For the remaining 32 bits, use a De Bruijn lookup. - - // Note: This does increase final code size, can shift left by 224 at runtime - // if codesize is more of a concern. - swap1 dup2 shr // [x >> r, r] - __RIGHTPAD(0x077cb531) // [0x077cb531..., x >> r, r] - mul // [(x >> r) * 0x077cb531, r] - 0xFB shr // [(x * 0x077cb531) >> 0xFB, r] - [FFS_DEBRUIJN] swap1 // [(x * 0x077cb531) >> 0xFB, debruijn_lookup, r] - byte // [b, r] - or // [b | r] - - // Return stack: [r] -} - -/// @dev Returns the number of set bits in `x`. -#define macro POP_COUNT() = takes (1) returns (1) { - // Input stack: [x] - - 0x00 not // [max, x] - dup1 dup3 lt // [is_not_max, max, x] - - swap2 // [x, max, is_not_max] - 0x03 dup3 div // [max / 0x03, x, max, is_not_max] - dup2 0x01 shr // [x >> 0x01, max / 0x03, x, max, is_not_max] - and // [(x >> 0x01) & (max / 0x03), x, max, is_not_max] - swap1 sub // [x, max, is_not_max] - - 0x05 dup3 div // [max / 0x05, x, max, is_not_max] - dup1 // [max / 0x05, max / 0x05, x, max, is_not_max] - dup3 0x02 shr // [x >> 0x02, max / 0x05, max / 0x05 x, max, is_not_max] - and // [(x >> 0x02) & (max / 0x05), max / 0x05, x, max, is_not_max] - swap2 // [max / 0x05, x, (x >> 0x02) & (max / 0x05), max, is_not_max] - and add // [x, max, is_not_max] - - 0x11 dup3 div // [max / 0x11, x, max, is_not_max] - swap1 // [x, max / 0x11, max, is_not_max] - dup1 0x04 shr // [x >> 0x04, x, max / 0x11, max, is_not_max] - add and // [x, max, is_not_max] - - swap1 0xFF // [0xFF, max, x, is_not_max] - swap1 div // [max / 0xFF, x, is_not_max] - mul // [(max / 0xFF) * x, is_not_max] - 0xF8 shr // [((max / 0xFF) * x) >> 0xF8, is_not_max] - 0x100 xor // [((max / 0xFF) * x) >> 0xF8) ^ 0x100, is_not_max] - mul // [((((max / 0xFF) * x) >> 0xF8) ^ 0x100) * is_not_max] - 0x100 xor // [(((((max / 0xFF) * x) >> 0xF8) ^ 0x100) * is_not_max) ^ 0x100] - - // Return stack: [c] -} - -/// @dev Returns 1, if the input is a power of 2. -#define macro IS_POW_OF_2() = takes (1) returns (1) { - // Input stack: [x] - - 0x01 // [1,x] - dup2 // [x,1,x] - sub // [x-1,x] - dup2 // [x,x-1,x] - and // [x & x-1,x] - swap1 // [x, x&x-1] - iszero // [x==0, x&x-1] - add // [(x==0) + (x&x-1)] - iszero // [(x==0) + (x&x-1) == 0] - - // Return stack: [c] -} - - -#define test FLS() = { - 0xFF 0x03 shl - FLS() - - 0x0a eq succeed jumpi - 0x00 dup1 revert - - succeed: -} - -#define test FFS() = { - 0xFF 0x03 shl - FFS() - - 0x03 eq succeed jumpi - 0x00 dup1 revert - - succeed: -} - -#define test POP_COUNT() = { - 0x01 dup1 - 0xFF shl or - POP_COUNT() - - 0x02 eq succeed jumpi - 0x00 dup1 revert - - succeed: -} - -#define test IS_POW_OF_2() = { - 0x05 dup1 - IS_POW_OF_2() - - 0x00 eq next jumpi - 0x00 dup1 revert - - next: - 0x08 dup1 - IS_POW_OF_2() - - 0x01 eq succeed jumpi - 0x00 dup1 revert - - succeed: -} \ No newline at end of file diff --git a/src/utils/__TEMP__fipsesfweqvmnghgiyyjyzxhruyzqbslBitPackLib.huff b/src/utils/__TEMP__fipsesfweqvmnghgiyyjyzxhruyzqbslBitPackLib.huff deleted file mode 100644 index 01993e90..00000000 --- a/src/utils/__TEMP__fipsesfweqvmnghgiyyjyzxhruyzqbslBitPackLib.huff +++ /dev/null @@ -1,104 +0,0 @@ -#define function packValue(bytes32, uint256, uint256, uint256) pure returns (bytes32) -#define function unpackValueFromRight(bytes32, uint256) pure returns (uint256) -#define function unpackValueFromLeft(bytes32, uint256) pure returns (uint256) -#define function unpackValueFromCenter(bytes32, uint256, uint256) pure returns (uint256) - -#define macro PACK_VALUE_WRAPPER() = takes (0) returns (0) { - 0x04 calldataload // [word] - 0x24 calldataload // [value, word] - 0x44 calldataload // [index, value, word] - 0x64 calldataload // [length, index, value, word] - PACK_VALUE() // [new_word] - 0x00 mstore // [] - 0x20 0x00 return -} - -#define macro UNPACK_FROM_RIGHT_WRAPPER() = takes (0) returns (0) { - 0x04 calldataload // [word] - 0x24 calldataload // [length, word] - UNPACK_FROM_RIGHT() // [value] - 0x00 mstore // [] - 0x20 0x00 return -} - -#define macro UNPACK_FROM_LEFT_WRAPPER() = takes (0) returns (0) { - 0x04 calldataload // [word] - 0x24 calldataload // [length, word] - UNPACK_FROM_LEFT() // [value] - 0x00 mstore // [] - 0x20 0x00 return -} - -#define macro UNPACK_FROM_CENTER_WRAPPER() = takes (0) returns (0) { - 0x04 calldataload // [word] - 0x24 calldataload // [length, word] - 0x44 calldataload // [length, index, word] - UNPACK_FROM_CENTER() // [value] - 0x00 mstore // [] - 0x20 0x00 return -} - -#define macro MAIN() = takes (0) returns (0) { - // Identify which function is being called using the 4 byte function signature - pc calldataload 0xE0 shr - - dup1 __FUNC_SIG(packValue) eq packValue jumpi - dup1 __FUNC_SIG(unpackValueFromRight) eq unpackValueFromRight jumpi - dup1 __FUNC_SIG(unpackValueFromLeft) eq unpackValueFromLeft jumpi - dup1 __FUNC_SIG(unpackValueFromCenter) eq unpackValueFromCenter jumpi - - 0x00 0x00 revert - - packValue: - PACK_VALUE_WRAPPER() - unpackValueFromRight: - UNPACK_FROM_RIGHT_WRAPPER() - unpackValueFromLeft: - UNPACK_FROM_LEFT_WRAPPER() - unpackValueFromCenter: - UNPACK_FROM_CENTER_WRAPPER() -} - -/// @title BitPackLib -/// @notice SPDX-License-Identifier: MIT -/// @author kadenzipfel -/// @notice Efficient bit packing library - -#define constant MAX = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff - -/// @notice Packs value of given length at index of given word -/// @dev Assumes index < 256 - length -#define macro PACK_VALUE() = takes (4) returns (1) { - // Input stack: // [length, index, value, word] - 0x100 sub sub // [shift, value, word] - shl or // [new_word] -} - -/// @notice Unpacks value of given length from right of word -/// @dev word & (~0 >> (256 - length)) -#define macro UNPACK_FROM_RIGHT() = takes (2) returns (1) { - // Input stack: // [length, word] - [MAX] // [not(0), length, word] - swap1 0x100 sub // [offset, not(0), word] - shr and // [value] -} - -/// @notice Unpacks value of given length from left of word -/// @dev word >> (256 - length) -#define macro UNPACK_FROM_LEFT() = takes (2) returns (1) { - // Input stack: // [length, word] - 0x100 sub // [shift, word] - shr // [value] -} - -/// @notice Unpacks value of given length from index of word -/// @dev Assumes index < 256 - length -/// (word & ((~0 >> 256 - length) << (256 - length - index))) >> (256 - length - index) -#define macro UNPACK_FROM_CENTER() = takes (3) returns (1) { - // Input stack: // [length, index, word] - 0x100 sub // [256 - length, index, word] - swap1 dup2 sub // [256 - length - index, 256 - length, word] - [MAX] swap1 swap2 shr // [~0 >> 256 - length, 256 - length - index, word] - dup2 shl swap1 swap2 and // [(word & ((~0 >> 256 - length) << (256 - length - index))), 256 - length - index] - swap1 shr // [value] -} diff --git a/src/utils/__TEMP__flqjyauokblaazsrdhqxfgjsonhnpjloMerkleProofLib.huff b/src/utils/__TEMP__flqjyauokblaazsrdhqxfgjsonhnpjloMerkleProofLib.huff deleted file mode 100644 index f55d7ee8..00000000 --- a/src/utils/__TEMP__flqjyauokblaazsrdhqxfgjsonhnpjloMerkleProofLib.huff +++ /dev/null @@ -1,86 +0,0 @@ -#define function verifyProof(bytes32, bytes32, bytes32[] calldata) pure returns (bool) - -#define macro VERIFY_PROOF_WRAPPER() = takes (0) returns (0) { - 0x04 calldataload // [root] - 0x24 calldataload // [leaf, root] - 0x64 // [proof_cd_ptr, leaf, root] - VERIFY_PROOF() // [is_valid] - 0x00 mstore // [] - 0x20 0x00 return -} - -#define macro MAIN() = takes (0) returns (0) { - pc calldataload 0xE0 shr - dup1 __FUNC_SIG(verifyProof) eq verifyProof jumpi - - 0x00 dup1 revert - - verifyProof: - VERIFY_PROOF_WRAPPER() -} - - -/// @title MerkleProofLib -/// @notice SPDX-License-Identifier: MIT -/// @author clabby -/// @notice Gas optimized merkle proof verification library -/// @notice Adapted from Solmate (https://github.com/transmissions11/solmate/blob/v7/src/utils/MerkleProofLib.sol) -/// @dev The `proof_cd_ptr` passed via the stack to this macro should point to the offset -/// of the proof array's length in the calldata. This macro assumes that the proof -/// array contains 32 byte values. - -/// @notice Verifies a merkle proof. -/// @param proof_cd_ptr Pointer to the length of the proof array. -/// @param leaf Leaf to prove inclusion of -/// @param root Root of the merkle tree -/// @return is_valid True if the inclusion of `leaf` in the merkle tree represented by -/// `root` was able to be proven, false if not. -#define macro VERIFY_PROOF() = takes (3) returns (1) { - // Input Stack: [proof_cd_ptr, leaf, root] - - // Get ending offset (ptr + 1 + proof_len * 0x20) of proof array - // and its starting offset (ptr + 0x20) - dup1 - 0x20 add - swap1 // [proof_cd_ptr, proof_cd_ptr + 0x20, leaf, root] - calldataload // [proof_arr_len, proof_cd_ptr + 0x20, leaf, root] - 0x05 shl // [proof_arr_len << 5, proof_cd_ptr + 0x20, leaf, root] - dup2 add // [proof_arr_len << 5 + proof_cd_ptr + 0x20, proof_cd_ptr + 0x20, leaf, root] - - // Stack description changed to reflect the vars' respective purposes in the loop - swap1 // [loop_offset, proof_arr_end, computed_hash, root] - - loop: - dup2 dup2 // [loop_offset, proof_arr_end, loop_offset, proof_arr_end, computed_hash, root] - lt // [loop_offset < proof_arr_end, loop_offset, proof_arr_end, computed_hash, root] - // If loop index is >= the proof arr end offset, finish the loop - iszero finish jumpi - - // Load data at proof_arr[loop_offset] - dup1 // [loop_offset, loop_offset, proof_arr_end, computed_hash, root] - calldataload // [proof_arr[loop_offset], loop_offset, proof_arr_end, computed_hash, root] - - dup1 // [proof_arr[loop_offset], proof_arr[loop_offset], loop_offset, proof_arr_end, computed_hash, root] - dup5 // [computed_hash, proof_arr[loop_offset], proof_arr[loop_offset], loop_offset, proof_arr_end, computed_hash, root] - gt // [computed_hash > proof_arr[loop_offset], proof_arr[loop_offset], loop_offset, proof_arr_end, computed_hash, root] - 0x05 shl // [(computed_hash > proof_arr[loop_offset]) << 5, proof_arr[loop_offset], loop_offset, proof_arr_end, computed_hash, root] - - dup5 // [computed_hash, (computed_hash > proof_arr[loop_offset]) << 5, proof_arr[loop_offset], loop_offset, proof_arr_end, computed_hash, root] - dup2 // [(computed_hash > proof_arr[loop_offset]) << 5, computed_hash, (computed_hash > proof_arr[loop_offset]) << 5, proof_arr[loop_offset], loop_offset, proof_arr_end, computed_hash, root] - mstore // [(computed_hash > proof_arr[loop_offset]) << 5, proof_arr[loop_offset], loop_offset, proof_arr_end, computed_hash, root] - - 0x20 xor // [((computed_hash > proof_arr[loop_offset]) << 5) ^ 0x20, proof_arr[loop_offset], loop_offset, proof_arr_end, computed_hash, root] - mstore // [loop_offset, proof_arr_end, computed_hash, root] - - // Compute new hash - 0x40 0x00 sha3 // [computed_hash_new, loop_offset, proof_arr_end, computed_hash, root] - swap3 pop // [loop_offset, proof_arr_end, computed_hash, root] - - // Increment loop offset by 0x20 - 0x20 add // [loop_offset + 0x20, proof_arr_end, computed_hash, root] - - loop jump - finish: - pop pop // [root, computed_hash] - eq // [root == computed_hash] -} \ No newline at end of file diff --git a/src/utils/__TEMP__fsghwzbaphyfhugpyejapdmpmaanfaqcTSOwnable.huff b/src/utils/__TEMP__fsghwzbaphyfhugpyejapdmpmaanfaqcTSOwnable.huff deleted file mode 100644 index ec480907..00000000 --- a/src/utils/__TEMP__fsghwzbaphyfhugpyejapdmpmaanfaqcTSOwnable.huff +++ /dev/null @@ -1,172 +0,0 @@ -/// SPDX-License-Identifier: MIT - -#define macro CONSTRUCTOR() = takes (0) returns (0) { - TSOWNABLE_CONSTRUCTOR() -} - -#define macro MAIN() = takes (0) returns (0) { - pc calldataload 0xe0 shr // [sig] - TSOWNABLE_MAIN() // [sig] - 0x00 dup1 revert // [] -} - -/// @title TSOwnable -/// @notice SPDX-License-Identifier: MIT -/// @author merkleplant (modified by @devtooligan) -/// @author asnared -/// @notice An Ownable Implementation using Two-Step Transfer Pattern - -#include "./Address.huff" -#include "./CommonErrors.huff" -#include "../auth/NonPayable.huff" - -// External Interface - -/// @notice Returns the current owner address. -#define function owner() view returns (address) - -/// @notice Returns the current pending owner address. -#define function pendingOwner() view returns (address) - -/// @notice Sets the pending owner address. -/// @dev Only callable by owner. -#define function setPendingOwner(address) nonpayable returns () - -/// @notice Accepts the ownership. -/// @dev Only callable by pending owner. -#define function acceptOwnership() nonpayable returns () - -/// @notice Emitted when new owner set. -#define event NewOwner(address, address) - -/// @notice Emitted when new pending owner set. -#define event NewPendingOwner(address, address) - -// Storage - -/// @notice Owner Storage Slot -#define constant OWNER_SLOT = FREE_STORAGE_POINTER() - -/// @notice Pending Owner Storage Slot -#define constant PENDING_OWNER_SLOT = FREE_STORAGE_POINTER() - -/// @notice Inner TSOwnable Constructor -#define macro TSOWNABLE_CONSTRUCTOR() = takes (0) returns (0) { - // Store msg.sender as owner - caller [OWNER_SLOT] sstore // [] -} - -/// @notice Only Owner Modifier -#define macro ONLY_OWNER_MODIFIER() = takes (0) returns (0) { - [OWNER_SLOT] sload // [owner] - caller eq authed jumpi // [] - ONLY_OWNER(0x00) // [] - authed: // [] -} - -/// @notice Only Pending Owner Modifier -#define macro ONLY_PENDING_OWNER_MODIFIER() = takes (0) returns (0) { - [PENDING_OWNER_SLOT] sload // [pending_owner] - caller eq // [msg.sender == pending_owner] - authed jumpi // [] - ONLY_PENDING_OWNER(0x00) // [] - authed: // [] -} - -// Mutating Functions - -/// @notice Set Pending Owner -/// @param newOwner The address of the new pending owner -#define macro OWNABLE_SET_PENDING_OWNER() = takes (0) returns (0) { - NON_PAYABLE() // [] - ONLY_OWNER_MODIFIER() // [] - - // Read argument and mask to address - 0x04 calldataload MASK_ADDRESS() // [newOwner] - - // Revert if address equals owner - dup1 caller // [owner, newOwner, newOwner] - eq iszero set jumpi // [newOwner] - ALREADY_OWNER(0x00) // [] - set: // [newOwner] - - // Duplicate address on stack - dup1 // [newOwner, newOwner] - - // Emit NewPendingOwner event - [OWNER_SLOT] sload // [owner, newOwner, newOwner] - __EVENT_HASH(NewPendingOwner) 0x00 0x00 // [offset, size, sig, owner, newOwner, newOwner] - log3 // [newOwner] - - // Store address as pending owner - [PENDING_OWNER_SLOT] sstore // [] - - // Stop execution - stop -} - -/// @notice Accept Ownership -/// @notice Allows the pending owner to become the owner -#define macro OWNABLE_ACCEPT_OWNERSHIP() = takes (0) returns (0) { - NON_PAYABLE() // [] - ONLY_PENDING_OWNER_MODIFIER() // [] - - // Emit NewOwner event - caller [OWNER_SLOT] sload // [owner, pending_owner] - __EVENT_HASH(NewOwner) 0x00 0x00 // [offset, size, sig, owner, pending_owner] - log3 // [] - - // Store msg.sender as owner - caller [OWNER_SLOT] sstore // [] - - // Clear pending owner - 0x00 [PENDING_OWNER_SLOT] sstore // [] - - // Stop execution - stop -} - -// View Functions - -/// @notice Get Owner -/// @notice Returns the current owner -#define macro OWNABLE_GET_OWNER() = takes (0) returns (0) { - NON_PAYABLE() // [] - [OWNER_SLOT] sload // [owner] - 0x00 mstore // [] - 0x20 0x00 return // [] -} - -/// @notice Get Pending Owner -/// @notice Returns the current pending owner -#define macro OWNABLE_GET_PENDING_OWNER() = takes (0) returns (0) { - NON_PAYABLE() // [] - [PENDING_OWNER_SLOT] sload // [pending_owner] - 0x00 mstore // [] - 0x20 0x00 return // [] -} - -// Function Dispatching -#define macro TSOWNABLE_MAIN() = takes (1) returns (1) { - // Input stack: [sig] - // Output stack: [sig] - - dup1 __FUNC_SIG(setPendingOwner) eq set_pending_owner jumpi - dup1 __FUNC_SIG(acceptOwnership) eq accept_ownership jumpi - dup1 __FUNC_SIG(owner) eq get_owner jumpi - dup1 __FUNC_SIG(pendingOwner) eq get_pending_owner jumpi - - // Bubble up to the parent macro - no_match jump - - set_pending_owner: - OWNABLE_SET_PENDING_OWNER() - accept_ownership: - OWNABLE_ACCEPT_OWNERSHIP() - get_owner: - OWNABLE_GET_OWNER() - get_pending_owner: - OWNABLE_GET_PENDING_OWNER() - - no_match: -} diff --git a/src/utils/__TEMP__fvsgbbyoimpybpmxmyrddbxuhherfeclBitPackLib.huff b/src/utils/__TEMP__fvsgbbyoimpybpmxmyrddbxuhherfeclBitPackLib.huff deleted file mode 100644 index 01993e90..00000000 --- a/src/utils/__TEMP__fvsgbbyoimpybpmxmyrddbxuhherfeclBitPackLib.huff +++ /dev/null @@ -1,104 +0,0 @@ -#define function packValue(bytes32, uint256, uint256, uint256) pure returns (bytes32) -#define function unpackValueFromRight(bytes32, uint256) pure returns (uint256) -#define function unpackValueFromLeft(bytes32, uint256) pure returns (uint256) -#define function unpackValueFromCenter(bytes32, uint256, uint256) pure returns (uint256) - -#define macro PACK_VALUE_WRAPPER() = takes (0) returns (0) { - 0x04 calldataload // [word] - 0x24 calldataload // [value, word] - 0x44 calldataload // [index, value, word] - 0x64 calldataload // [length, index, value, word] - PACK_VALUE() // [new_word] - 0x00 mstore // [] - 0x20 0x00 return -} - -#define macro UNPACK_FROM_RIGHT_WRAPPER() = takes (0) returns (0) { - 0x04 calldataload // [word] - 0x24 calldataload // [length, word] - UNPACK_FROM_RIGHT() // [value] - 0x00 mstore // [] - 0x20 0x00 return -} - -#define macro UNPACK_FROM_LEFT_WRAPPER() = takes (0) returns (0) { - 0x04 calldataload // [word] - 0x24 calldataload // [length, word] - UNPACK_FROM_LEFT() // [value] - 0x00 mstore // [] - 0x20 0x00 return -} - -#define macro UNPACK_FROM_CENTER_WRAPPER() = takes (0) returns (0) { - 0x04 calldataload // [word] - 0x24 calldataload // [length, word] - 0x44 calldataload // [length, index, word] - UNPACK_FROM_CENTER() // [value] - 0x00 mstore // [] - 0x20 0x00 return -} - -#define macro MAIN() = takes (0) returns (0) { - // Identify which function is being called using the 4 byte function signature - pc calldataload 0xE0 shr - - dup1 __FUNC_SIG(packValue) eq packValue jumpi - dup1 __FUNC_SIG(unpackValueFromRight) eq unpackValueFromRight jumpi - dup1 __FUNC_SIG(unpackValueFromLeft) eq unpackValueFromLeft jumpi - dup1 __FUNC_SIG(unpackValueFromCenter) eq unpackValueFromCenter jumpi - - 0x00 0x00 revert - - packValue: - PACK_VALUE_WRAPPER() - unpackValueFromRight: - UNPACK_FROM_RIGHT_WRAPPER() - unpackValueFromLeft: - UNPACK_FROM_LEFT_WRAPPER() - unpackValueFromCenter: - UNPACK_FROM_CENTER_WRAPPER() -} - -/// @title BitPackLib -/// @notice SPDX-License-Identifier: MIT -/// @author kadenzipfel -/// @notice Efficient bit packing library - -#define constant MAX = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff - -/// @notice Packs value of given length at index of given word -/// @dev Assumes index < 256 - length -#define macro PACK_VALUE() = takes (4) returns (1) { - // Input stack: // [length, index, value, word] - 0x100 sub sub // [shift, value, word] - shl or // [new_word] -} - -/// @notice Unpacks value of given length from right of word -/// @dev word & (~0 >> (256 - length)) -#define macro UNPACK_FROM_RIGHT() = takes (2) returns (1) { - // Input stack: // [length, word] - [MAX] // [not(0), length, word] - swap1 0x100 sub // [offset, not(0), word] - shr and // [value] -} - -/// @notice Unpacks value of given length from left of word -/// @dev word >> (256 - length) -#define macro UNPACK_FROM_LEFT() = takes (2) returns (1) { - // Input stack: // [length, word] - 0x100 sub // [shift, word] - shr // [value] -} - -/// @notice Unpacks value of given length from index of word -/// @dev Assumes index < 256 - length -/// (word & ((~0 >> 256 - length) << (256 - length - index))) >> (256 - length - index) -#define macro UNPACK_FROM_CENTER() = takes (3) returns (1) { - // Input stack: // [length, index, word] - 0x100 sub // [256 - length, index, word] - swap1 dup2 sub // [256 - length - index, 256 - length, word] - [MAX] swap1 swap2 shr // [~0 >> 256 - length, 256 - length - index, word] - dup2 shl swap1 swap2 and // [(word & ((~0 >> 256 - length) << (256 - length - index))), 256 - length - index] - swap1 shr // [value] -} diff --git a/src/utils/__TEMP__gbfutonvmuwvpsgnhyhrztoimrzkyqskTSOwnable.huff b/src/utils/__TEMP__gbfutonvmuwvpsgnhyhrztoimrzkyqskTSOwnable.huff deleted file mode 100644 index ec480907..00000000 --- a/src/utils/__TEMP__gbfutonvmuwvpsgnhyhrztoimrzkyqskTSOwnable.huff +++ /dev/null @@ -1,172 +0,0 @@ -/// SPDX-License-Identifier: MIT - -#define macro CONSTRUCTOR() = takes (0) returns (0) { - TSOWNABLE_CONSTRUCTOR() -} - -#define macro MAIN() = takes (0) returns (0) { - pc calldataload 0xe0 shr // [sig] - TSOWNABLE_MAIN() // [sig] - 0x00 dup1 revert // [] -} - -/// @title TSOwnable -/// @notice SPDX-License-Identifier: MIT -/// @author merkleplant (modified by @devtooligan) -/// @author asnared -/// @notice An Ownable Implementation using Two-Step Transfer Pattern - -#include "./Address.huff" -#include "./CommonErrors.huff" -#include "../auth/NonPayable.huff" - -// External Interface - -/// @notice Returns the current owner address. -#define function owner() view returns (address) - -/// @notice Returns the current pending owner address. -#define function pendingOwner() view returns (address) - -/// @notice Sets the pending owner address. -/// @dev Only callable by owner. -#define function setPendingOwner(address) nonpayable returns () - -/// @notice Accepts the ownership. -/// @dev Only callable by pending owner. -#define function acceptOwnership() nonpayable returns () - -/// @notice Emitted when new owner set. -#define event NewOwner(address, address) - -/// @notice Emitted when new pending owner set. -#define event NewPendingOwner(address, address) - -// Storage - -/// @notice Owner Storage Slot -#define constant OWNER_SLOT = FREE_STORAGE_POINTER() - -/// @notice Pending Owner Storage Slot -#define constant PENDING_OWNER_SLOT = FREE_STORAGE_POINTER() - -/// @notice Inner TSOwnable Constructor -#define macro TSOWNABLE_CONSTRUCTOR() = takes (0) returns (0) { - // Store msg.sender as owner - caller [OWNER_SLOT] sstore // [] -} - -/// @notice Only Owner Modifier -#define macro ONLY_OWNER_MODIFIER() = takes (0) returns (0) { - [OWNER_SLOT] sload // [owner] - caller eq authed jumpi // [] - ONLY_OWNER(0x00) // [] - authed: // [] -} - -/// @notice Only Pending Owner Modifier -#define macro ONLY_PENDING_OWNER_MODIFIER() = takes (0) returns (0) { - [PENDING_OWNER_SLOT] sload // [pending_owner] - caller eq // [msg.sender == pending_owner] - authed jumpi // [] - ONLY_PENDING_OWNER(0x00) // [] - authed: // [] -} - -// Mutating Functions - -/// @notice Set Pending Owner -/// @param newOwner The address of the new pending owner -#define macro OWNABLE_SET_PENDING_OWNER() = takes (0) returns (0) { - NON_PAYABLE() // [] - ONLY_OWNER_MODIFIER() // [] - - // Read argument and mask to address - 0x04 calldataload MASK_ADDRESS() // [newOwner] - - // Revert if address equals owner - dup1 caller // [owner, newOwner, newOwner] - eq iszero set jumpi // [newOwner] - ALREADY_OWNER(0x00) // [] - set: // [newOwner] - - // Duplicate address on stack - dup1 // [newOwner, newOwner] - - // Emit NewPendingOwner event - [OWNER_SLOT] sload // [owner, newOwner, newOwner] - __EVENT_HASH(NewPendingOwner) 0x00 0x00 // [offset, size, sig, owner, newOwner, newOwner] - log3 // [newOwner] - - // Store address as pending owner - [PENDING_OWNER_SLOT] sstore // [] - - // Stop execution - stop -} - -/// @notice Accept Ownership -/// @notice Allows the pending owner to become the owner -#define macro OWNABLE_ACCEPT_OWNERSHIP() = takes (0) returns (0) { - NON_PAYABLE() // [] - ONLY_PENDING_OWNER_MODIFIER() // [] - - // Emit NewOwner event - caller [OWNER_SLOT] sload // [owner, pending_owner] - __EVENT_HASH(NewOwner) 0x00 0x00 // [offset, size, sig, owner, pending_owner] - log3 // [] - - // Store msg.sender as owner - caller [OWNER_SLOT] sstore // [] - - // Clear pending owner - 0x00 [PENDING_OWNER_SLOT] sstore // [] - - // Stop execution - stop -} - -// View Functions - -/// @notice Get Owner -/// @notice Returns the current owner -#define macro OWNABLE_GET_OWNER() = takes (0) returns (0) { - NON_PAYABLE() // [] - [OWNER_SLOT] sload // [owner] - 0x00 mstore // [] - 0x20 0x00 return // [] -} - -/// @notice Get Pending Owner -/// @notice Returns the current pending owner -#define macro OWNABLE_GET_PENDING_OWNER() = takes (0) returns (0) { - NON_PAYABLE() // [] - [PENDING_OWNER_SLOT] sload // [pending_owner] - 0x00 mstore // [] - 0x20 0x00 return // [] -} - -// Function Dispatching -#define macro TSOWNABLE_MAIN() = takes (1) returns (1) { - // Input stack: [sig] - // Output stack: [sig] - - dup1 __FUNC_SIG(setPendingOwner) eq set_pending_owner jumpi - dup1 __FUNC_SIG(acceptOwnership) eq accept_ownership jumpi - dup1 __FUNC_SIG(owner) eq get_owner jumpi - dup1 __FUNC_SIG(pendingOwner) eq get_pending_owner jumpi - - // Bubble up to the parent macro - no_match jump - - set_pending_owner: - OWNABLE_SET_PENDING_OWNER() - accept_ownership: - OWNABLE_ACCEPT_OWNERSHIP() - get_owner: - OWNABLE_GET_OWNER() - get_pending_owner: - OWNABLE_GET_PENDING_OWNER() - - no_match: -} diff --git a/src/utils/__TEMP__gzlramplmuvmnsgrxrurevmmugyklixkEthers.huff b/src/utils/__TEMP__gzlramplmuvmnsgrxrurevmmugyklixkEthers.huff deleted file mode 100644 index 12fda5c0..00000000 --- a/src/utils/__TEMP__gzlramplmuvmnsgrxrurevmmugyklixkEthers.huff +++ /dev/null @@ -1,47 +0,0 @@ - -// Receives ether -#define function isPayable() payable returns (uint256) -#define function nonPayable() nonpayable returns (uint256) - -// Match the function selector -#define macro MAIN() = takes (0) returns (0) { - pc calldataload 0xe0 shr - - dup1 __FUNC_SIG(isPayable) eq payable_jump jumpi - dup1 __FUNC_SIG(nonPayable) eq non_payable_jump jumpi - - // Revert if no function selectors match - reverts: - 0x00 dup1 revert - - non_payable_jump: - callvalue iszero iszero reverts jumpi - payable_jump: - balance 0x00 mstore - 0x20 0x00 return -} - -/// @title Ethers -/// @notice SPDX-License-Identifier: MIT -/// @author asnared -/// @notice Utilities for working with ether at a low level - -/// @notice Sends an amount of ether to the specified [amount, address] -#define macro SEND_ETH() = takes (2) returns (1) { - // Input Stack: [amount, address] - - // Send the ether - 0x00 // [0, amount, address] - dup1 // [0, 0, amount, address] - dup1 // [0, 0, 0, amount, address] - dup1 // [0, 0, 0, 0, amount, address] - dup5 // [amount, 0, 0, 0, 0, amount, address] - dup7 // [address, amount, 0, 0, 0, 0, amount] - gas // [gas, address, amount, 0, 0, 0, 0, amount, address] - call // [success, amount, address] - - // Clean the stack - swap2 // [address, amount, success] - pop // [success, address] - pop // [success] -} \ No newline at end of file diff --git a/src/utils/__TEMP__hkejoojmditrgmsogdgtpmxmtwqmpdocReentrancyGuard.huff b/src/utils/__TEMP__hkejoojmditrgmsogdgtpmxmtwqmpdocReentrancyGuard.huff deleted file mode 100644 index 33534b5b..00000000 --- a/src/utils/__TEMP__hkejoojmditrgmsogdgtpmxmtwqmpdocReentrancyGuard.huff +++ /dev/null @@ -1,127 +0,0 @@ - -#define function state() view returns (uint256) -#define function lock() nonpayable returns () -#define function unlock() nonpayable returns () - -#define macro LOCK_WRAPPER() = takes (0) returns (0) { - LOCK() - stop -} - -#define macro UNLOCK_WRAPPER() = takes (0) returns (0) { - UNLOCK() - stop -} - -#define macro GET_STATE() = takes (0) returns (0) { - [LOCKED_SLOT] sload // [LOCKED] - 0x00 mstore // [] - 0x20 0x00 return // [] -} - -#define macro MAIN() = takes (0) returns (0) { - pc calldataload 0xE0 shr // [selector] - - dup1 __FUNC_SIG(state) eq state_jump jumpi - dup1 __FUNC_SIG(lock) eq lock_jump jumpi - dup1 __FUNC_SIG(unlock) eq unlock_jump jumpi - - DISPATCH_ERROR(0x00) - - state_jump: - GET_STATE() - - lock_jump: - LOCK_WRAPPER() - - unlock_jump: - UNLOCK_WRAPPER() -} - -/// @title Reentrancy Guard -/// @notice SPDX-License-Identifier: MIT -/// @author rayquaza7 -/// @notice Gas optimized reentrancy guard for smart contracts. -/// @notice Adapted from Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/ReentrancyGuard.sol) - -#include "./CommonErrors.huff" - -// Interface -#define function lock() nonpayable returns () -#define function unlock() nonpayable returns () - -// Constants -#define constant LOCKED_SLOT = FREE_STORAGE_POINTER() -#define constant _UNLOCKED = 0x01 -#define constant _LOCKED = 0x02 - -/// @title Lock -/// @notice Locks the contract to prevent reentrancy -#define fn LOCK() = takes (0) returns (0) { - [_LOCKED] // [0x02] - dup1 // [0x02, 0x02] - [LOCKED_SLOT] // [locked_slot, 0x02, 0x02] - sload // [locked_slot_value, 0x02, 0x02] - lt // [locked_slot_value < 0x02, 0x02] - lock jumpi - - // Otherwise revert with re-entrancy - REENTRANCY(0x00) - - lock: - [LOCKED_SLOT] sstore -} - -/// @title Unlock -/// @notice Unlocks the contract -#define fn UNLOCK() = takes (0) returns (0) { - [_UNLOCKED] [LOCKED_SLOT] sstore -} - -#define macro REENTRANCY_GUARD_MAIN() = takes (0) returns (0) { - pc calldataload 0xE0 shr - - dup1 __FUNC_SIG(lock) eq lock_jump jumpi - dup1 __FUNC_SIG(unlock) eq unlock_jump jumpi - - reentrancy_sig_no_match_found jump - - lock_jump: - LOCK() - unlock_jump: - UNLOCK() - - reentrancy_sig_no_match_found: -} - -/// @notice Test Unlocking -#define test TEST_LOCK() = takes (0) returns (0) { - // Make sure our slot is set to the UNLOCKED state - UNLOCK() - - // Lock - LOCK() - [LOCKED_SLOT] sload - - // We expect the locked slot to be set to 2 - the LOCKED state - 0x02 eq succeed jumpi - 0x00 dup1 revert - - succeed: -} - -/// @notice Test Unlocking -#define test TEST_UNLOCK() = takes (0) returns (0) { - // Make sure our slot is set to the LOCKED state - LOCK() - - // Unlock - UNLOCK() - [LOCKED_SLOT] sload - - // We expect the locked slot to be set to 1 - the UNLOCKED state - 0x01 eq succeed jumpi - 0x00 dup1 revert - - succeed: -} \ No newline at end of file diff --git a/src/utils/__TEMP__hutfgjhkcylvhdduoakglqjyfagmmbgbJumpTableUtil.huff b/src/utils/__TEMP__hutfgjhkcylvhdduoakglqjyfagmmbgbJumpTableUtil.huff deleted file mode 100644 index b42ce920..00000000 --- a/src/utils/__TEMP__hutfgjhkcylvhdduoakglqjyfagmmbgbJumpTableUtil.huff +++ /dev/null @@ -1,149 +0,0 @@ -#define function getJumpdestMem(uint256) view returns (uint256) -#define function getJumpdestStack(uint256) view returns (uint256) -#define function getJumpdestMemPacked(uint256) view returns (uint256) -#define function getJumpdestStackPacked(uint256) view returns (uint256) - -#define jumptable TEST_TABLE { - test_label_a test_label_b test_label_c test_label_d -} - -#define jumptable__packed TEST_TABLE_PACKED { - test_label_a test_label_b test_label_c test_label_d -} - -#define macro GET_JUMPDEST_MEM_WRAPPER() = takes (0) returns (0) { - __tablestart(TEST_TABLE) // [table_start] - 0x04 calldataload // [n, table_start] - - // Load a jumpdest inside of `TEST_TABLE` at index `n` into - // memory at 0x00. - LOAD_FROM_JT(0x00) // [] - 0x20 0x00 return -} - -#define macro GET_JUMPDEST_STACK_WRAPPER() = takes (0) returns (0) { - __tablestart(TEST_TABLE) // [table_start] - 0x04 calldataload // [n, table_start] - RETRIEVE_FROM_JT() // [jumpdest_pc] - - // Store our jumpdest_pc in memory & return it - 0x00 mstore // [] - 0x20 0x00 return -} - -#define macro GET_JUMPDEST_MEM_PACKED_WRAPPER() = takes (0) returns (0) { - __tablestart(TEST_TABLE_PACKED) // [table_start] - 0x04 calldataload // [n, table_start] - - // Store the retrieved jumpdest at 0x00 in memory. - // Since `LOAD_FROM_PACKED_JT` only retrieves 2 bytes - // from the contract's code in the `codecopy` op, we - // need to pass our desired memory pointer + 0x1e (30 bytes) - LOAD_FROM_PACKED_JT(0x1e) // [] - 0x20 0x00 return -} - -#define macro GET_JUMPDEST_STACK_PACKED_WRAPPER() = takes (0) returns (0) { - __tablestart(TEST_TABLE_PACKED) // [table_start] - 0x04 calldataload // [n, table_start] - RETRIEVE_FROM_PACKED_JT() // [jumpdest_pc] - - // Store our jumpdest_pc in memory & return it - 0x00 mstore // [] - 0x20 0x00 return -} - -#define macro MAIN() = takes (0) returns (0) { - pc calldataload 0xE0 shr - dup1 __FUNC_SIG(getJumpdestMem) eq get_jumpdest_mem jumpi - dup1 __FUNC_SIG(getJumpdestStack) eq get_jumpdest_stack jumpi - dup1 __FUNC_SIG(getJumpdestMemPacked) eq get_jumpdest_mem_packed jumpi - dup1 __FUNC_SIG(getJumpdestStackPacked) eq get_jumpdest_stack_packed jumpi - - // Revert if no function signature matched - test_label_d jump - - get_jumpdest_mem: - GET_JUMPDEST_MEM_WRAPPER() - get_jumpdest_stack: - GET_JUMPDEST_MEM_WRAPPER() - get_jumpdest_mem_packed: - GET_JUMPDEST_MEM_PACKED_WRAPPER() - get_jumpdest_stack_packed: - GET_JUMPDEST_STACK_PACKED_WRAPPER() - - // Test labels included in `TEST_TABLE` - test_label_a: - test_label_b: - test_label_c: - test_label_d: - 0x00 dup1 revert -} - - -/// @title JumpTableUtil -/// @notice SPDX-License-Identifier: MIT -/// @author clabby -/// @notice Utility macros for retrieving jumpdest pcs from jump tables - -/// @notice Loads a jumpdest stored in a jumptable into memory at `mem_ptr` -/// -/// @param mem_ptr The memory location to load the 2 byte jumpdest into -/// @param index The index of the jumpdest within the jumptable -/// @param table_start The offset of the jumptable in the contract's bytecode -#define macro LOAD_FROM_JT(mem_ptr) = takes (2) returns (1) { - // Input stack: [index, table_start] - - 0x05 shl add // [table_start + index * 0x20] - 0x20 swap1 // [table_start + index * 0x20, 0x20] - // [mem_ptr, table_start + index * 0x20, 0x20] - codecopy // [] - - // Return stack: [] -} - -/// @notice Retrieves a jumpdest stored in a jumptable and puts it on the stack -/// -/// @param index The index of the jumpdest within the jumptable -/// @param table_start The offset of the jumptable in the contract's bytecode -#define macro RETRIEVE_FROM_JT() = takes (2) returns (1) { - // Input stack: [index, table_start] - - LOAD_FROM_JT(0x00) // [] - 0x00 mload // [res] - - // Return stack: [res] -} - -/// @notice Loads a jumpdest stored in a packed jumptable into memory at `mem_ptr` -/// @dev This macro only loads 2 bytes from the contract code, so make sure to account -/// for this when passing a `mem_ptr`. I.e., if we want to store the jumpdest pc -/// at offset `x`, we would pass in `x + 0x1e` as the `mem_ptr` argument. -/// -/// @param mem_ptr The memory location to load the 2 byte jumpdest into -/// @param index The index of the jumpdest within the packed jumptable -/// @param table_start The offset of the packed jumptable in the contract's bytecode -#define macro LOAD_FROM_PACKED_JT(mem_ptr) = takes (2) returns (1) { - // Input stack: [index, table_start] - - 0x01 shl add // [table_start + index * 0x02] - 0x02 swap1 // [table_start + index * 0x02, 0x02] - // [mem_ptr, table_start + index * 0x02, 0x02] - codecopy // [] - - // Return stack: [] -} - -/// @notice Retrieves a jumpdest stored in a packed jumptable and puts it on the stack -/// -/// @param index The index of the jumpdest within the packed jumptable -/// @param table_start The offset of the packed jumptable in the contract's bytecode -#define macro RETRIEVE_FROM_PACKED_JT() = takes (2) returns (1) { - // Input stack: [index, table_start] - - LOAD_FROM_PACKED_JT(0x1e) - // [] - 0x00 mload // [res] - - // Return stack: [res] -} diff --git a/src/utils/__TEMP__iuxgytjvcjspqzqpxtbelyxicffhqxfrSSTORE2.huff b/src/utils/__TEMP__iuxgytjvcjspqzqpxtbelyxicffhqxfrSSTORE2.huff deleted file mode 100644 index da214168..00000000 --- a/src/utils/__TEMP__iuxgytjvcjspqzqpxtbelyxicffhqxfrSSTORE2.huff +++ /dev/null @@ -1,132 +0,0 @@ - -// #define function read(address, uint256) view returns (bytes memory) -// #define function read(address, uint256, uint256) view returns (bytes memory) -#define function read(address) view returns (bytes memory) -#define function write(bytes memory) nonpayable returns (address) - -#define macro SSTORE2_WRITE_WRAPPER() = takes (0) returns (0) { - SSTORE2_WRITE() // [address] - 0x00 mstore // [] - 0x20 0x00 return // [] -} - -#define macro SSTORE2_READ_WRAPPER() = takes (0) returns (0) { - 0x04 calldataload // [pointer] - SSTORE2_READ() // [data_length_in_memory] - 0x00 return // [] -} - -#define macro SSTORE2_READ_AT_WRAPPER() = takes (0) returns (0) { - 0x24 calldataload // [start] - 0x04 calldataload // [pointer, start] - SSTORE2_READ_AT() // [data_length_in_memory] - 0x00 return // [] -} - -#define macro SSTORE2_READ_BETWEEN_WRAPPER() = takes (0) returns (0) { - 0x44 calldataload // [end] - 0x24 calldataload // [start, end] - 0x04 calldataload // [pointer, start, end] - SSTORE2_READ_BETWEEN() // [data_length_in_memory] - 0x00 return // [] -} - -#define macro MAIN() = takes (0) returns (0) { - pc calldataload 0xE0 shr // [selector] - - dup1 __FUNC_SIG(write) eq write_jump jumpi - dup1 __FUNC_SIG(read) eq read_jump jumpi - dup1 __FUNC_SIG("read(address,uint256)") eq read_at_jump jumpi - dup1 __FUNC_SIG("read(address,uint256,uint256)") eq read_between_jump jumpi - - 0x00 dup1 revert - - write_jump: - SSTORE2_WRITE_WRAPPER() - - read_jump: - SSTORE2_READ_WRAPPER() - - read_at_jump: - SSTORE2_READ_AT_WRAPPER() - - read_between_jump: - SSTORE2_READ_BETWEEN_WRAPPER() -} - -/// @title SSTORE2 -/// @notice SPDX-License-Identifier: MIT -/// @author asnared -/// @notice Faster & cheaper contract key-value storage for Ethereum Contracts -/// @notice Adapted from 0xsequence/sstore2 (https://github.com/0xsequence/sstore2) - -#include "./Bytecode.huff" -#include "./CommonErrors.huff" - -#define constant TYPE_UINT_256_MAX = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff - -/// @notice Stores `_data` and returns `pointer` as key for later retrieval -/// @dev The pointer is a contract address with `_data` as code -/// @param {_data} [bytes memory] to be written -/// @return pointer Pointer to the written `_data` -#define macro SSTORE2_WRITE() = takes (0) returns (1) { - // Load the data memory pointer - 0x04 calldataload // [&_data] - dup1 0x04 add calldataload swap1 // [&_data, _data.length] - - // Create the contract creation code - CREATION_CODE_FOR() // [&_data, _data.length] - - // Deploy the contract - swap1 // [_data.length, &_data] - 0x0f add // [size, &_data] - 0x00 // [offset, size, &_data] - 0x00 // [value, offset, size, &_data] - create // [address, &_data] - - // Check that the address is non-zero - dup1 iszero iszero success jumpi // [address, &_data] - CREATE_FAILED(0x00) - success: - - // Clean the stack and return the address - swap1 pop // [address] -} - -/// @notice Reads the contents of the `_pointer` code as data, skips the first byte -/// @dev The function is intended for reading pointers generated by `write` -/// @param _pointer to be read -/// @return data read from `_pointer` contract -#define macro SSTORE2_READ() = takes (1) returns (1) { - // Input Stack: [_pointer] - // We start at 1 because the first byte are zeros to prevent the contract from being called - 0x01 // [_start, _pointer] - [TYPE_UINT_256_MAX] // [_end, _start, _pointer] - swap2 // [_pointer, _start, _end] - CODE_AT() // [code] -} - -/// @notice Reads the contents of the `_pointer` code as data, skips the first byte -/// @dev The function is intended for reading pointers generated by `write` -/// @param _pointer to be read -/// @param _start number of bytes to skip -/// @return data read from `_pointer` contract -#define macro SSTORE2_READ_AT() = takes (2) returns (1) { - // Input Stack: [_pointer, _start] - swap1 // [_start, _pointer] - [TYPE_UINT_256_MAX] // [_end, _start, _pointer] - swap2 // [_pointer, _start, _end] - CODE_AT() // [code] -} - -/// @notice Reads the contents of the `_pointer` code as data, skips the first byte -/// @dev The function is intended for reading pointers generated by `write` -/// @param _pointer to be read -/// @param _start number of bytes to skip -/// @param _end index before which to end extraction -/// @return data read from `_pointer` contract -#define macro SSTORE2_READ_BETWEEN() = takes (3) returns (1) { - // Input Stack: [_pointer, _start, _end] - CODE_AT() // [code] -} - diff --git a/src/utils/__TEMP__kfkjwomkxvqpeatpkwmzsmvjaneohelmRefunded.huff b/src/utils/__TEMP__kfkjwomkxvqpeatpkwmzsmvjaneohelmRefunded.huff deleted file mode 100644 index 6dde1042..00000000 --- a/src/utils/__TEMP__kfkjwomkxvqpeatpkwmzsmvjaneohelmRefunded.huff +++ /dev/null @@ -1,97 +0,0 @@ - -#define function refundedCall() payable returns () -#define function nonRefundedCall() payable returns () - -#define event NonRefundedCall(address) - -#define macro MAIN() = takes (0) returns (0) { - pc calldataload 0xe0 shr - - dup1 __FUNC_SIG(refundedCall) eq refunded_call jumpi - dup1 __FUNC_SIG(nonRefundedCall) eq non_refunded_call jumpi - - 0x00 dup1 revert - - refunded_logic: - caller __EVENT_HASH(NonRefundedCall) 0x00 0x00 log2 - __Refund_Return_Dest jump - - refunded_call: - REFUNDED(refunded_logic) - stop - non_refunded_call: - caller __EVENT_HASH(NonRefundedCall) 0x00 0x00 log2 - stop -} - -/// @title Refunded -/// @notice SPDX-License-Identifier: MIT -/// @author asnared -/// @notice Efficient gas refunds distributed through a modifier -/// @notice Adapted from Zolidity (https://github.com/z0r0z/zolidity/blob/main/src/utils/Refunded.sol) - -#include "./Errors.huff" -#include "./ReentrancyGuard.huff" - -/// @notice The base cost of refunding -#define constant BASE_COST = 0x6359 // 25433 - -/// @notice The maximum amount of gas that can be refunded -#define constant GAS_PRICE_MAX = 0x9502F9000 // 4e10 - -// Refunded custom errors -#define constant MAX_GAS_ERROR = 0x4d41585f47415300000000000000000000000000000000000000000000000000 -#define constant MAX_GAS_LENGTH = 0x07 - -/// @notice Refunds contract calls up to a maximum of 4e10 gas -/// @notice Modified functions over 21k gas benefit most from a refund -#define macro REFUNDED(dest) = takes (0) returns (0) { - // Get the starting amount of gas - gas // [gasLeft] - - // Prevent Reentrancy - LOCK() // [gasLeft] - - basefee [GAS_PRICE_MAX] add // [currMaxGas, gasLeft] - gasprice gt iszero // [!(gasPrice > currMaxGas), gasLeft] - __Safe_Gas_Refund__j jumpi // [gasLeft] - MAX_GAS(0x00) - - __Safe_Gas_Refund__j: - - // The below attempts to mimic `_;` using a jump - // NOTE: This must jump back to `__Refund_Return_Dest` to complete the refund - jump - __Refund_Return_Dest: - - // Calculate refund amount - gas swap1 sub // [gasUsed] - [BASE_COST] add // [gasUsed + BASE_COST] - gasprice mul // [(gasUsed + BASE_COST) * gasPrice] - - // Refund the gas to origin - 0x00 // [retOffset, value] - 0x00 // [argSize, retOffset, value] - 0x00 // [argOffset, argSize, retOffset, value] - 0x00 // [retSize, argOffset, argSize, retOffset, value] - swap4 // [value, argOffset, argSize, retOffset, retSize] - origin // [to, value, argOffset, argSize, retOffset, retSize] - gas // [gas, to, value, argOffset, argSize, retOffset, retSize] - call - iszero iszero __Refund_Successful__j jumpi - 0x00 dup1 revert - - // The refund was successful! - __Refund_Successful__j: - - // Finally, unlock the guard - UNLOCK() -} - -/// @notice Reverts with an "MAX_GAS" message if the condition is false -#define macro MAX_GAS(condition) = takes (0) returns (0) { - [MAX_GAS_ERROR] // ["MAX_GAS"] - [MAX_GAS_LENGTH] // [7 (length), "MAX_GAS"] - // [condition, 7 (length), "MAX_GAS"] - REQUIRE() // [] -} \ No newline at end of file diff --git a/src/utils/__TEMP__kkfsbfpunncyiouwtmltswyzljambbxxShuffling.huff b/src/utils/__TEMP__kkfsbfpunncyiouwtmltswyzljambbxxShuffling.huff deleted file mode 100644 index 74d30ae0..00000000 --- a/src/utils/__TEMP__kkfsbfpunncyiouwtmltswyzljambbxxShuffling.huff +++ /dev/null @@ -1,68 +0,0 @@ -#define function oneWayShuffle(bytes32 seed, uint256 index, uint256 count, uint256 rounds) view returns (uint256) - -#define macro SHUFFLE_WRAPPER() = takes (0) returns (0) { - 0x64 calldataload // [rounds] - 0x44 calldataload // [count, rounds] - 0x24 calldataload // [index, count, rounds] - 0x04 calldataload // [seed, index, count, rounds] - MECHS__ONE_WAY_SHUFFLE(0x60, 0x80) // [index'] - 0x00 mstore 0x20 0x00 return // [] -} - -#define macro MAIN() = takes (0) returns (0) { - pc calldataload 0xE0 shr // [selector] - - dup1 __FUNC_SIG(oneWayShuffle) eq shuffle jumpi - - 0x00 dup1 revert - - shuffle: - SHUFFLE_WRAPPER() -} - - -/// @title Shuffling -/// @notice SPDX-License-Identifier: MIT -/// @author Philogy -/// @author asnared -/// @notice Refactored algorithms for shuffling and other bitwise algorithms. -/// @notice Adapted from Ethereum Consensus Specs (https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#compute_shuffled_index) - -#include "./Address.huff" -#include "./Ternary.huff" - -#include "../math/Math.huff" - -// Constants -#define constant POS_MASK = 0xffffffff00 - -/// @notice Shuffling Algorithm -#define macro MECHS__ONE_WAY_SHUFFLE(mem1, mem2) = takes (4) returns (1) { - // Input Stack: [seed, index, index_count, iters] - // Output Stack: [index'] - - __Mechs__shuffleContinue: // [seed, index, index_count, iters] - mstore // [index, index_count, iters] - 0x20 sha3 // [seed', index, index_count, iters] - dup3 dup1 // [index_count, index_count, seed' index, index_count, iters] - dup3 mod // [pivot, index_count, seed', index, index_count, iters] - dup4 dup3 // [index_count, index, pivot, index_count, seed', index, index_count, iters] - sub add mod // [flip, seed', index, index_count, iters] - dup3 dup2 MAX() // [position, flip, seed', index, index_count, iters] - dup1 [POS_MASK] and // [masked_position, position, flip, seed', index, index_count, iters] - mstore // [position, flip, seed', index, index_count, iters] - 0x40 sha3 // [rand2, position, flip, seed', index, index_count, iters] - swap1 0xff and shr // [rand_bit_unmasked, flip, seed', index, index_count, iters] - 0x1 and // [rand_bit, flip, seed', index, index_count, iters] - swap2 swap3 swap2 // [rand_bit, flip, index, seed', index_count, iters] - NOT_TERNARY() // [index', seed', index_count, iters] - swap1 swap3 // [iters, index', index_count, seed'] - UNSAFE_SUB() swap3 // [seed', index', index_count, iters'] - - // Continue if iters > 0 - dup4 __Mechs__shuffleContinue jumpi - - // Return the index - pop swap2 pop pop // [index'] -} - diff --git a/src/utils/__TEMP__ldwwbkwihqrpqdglcwrdylrneycegnebReentrancyGuard.huff b/src/utils/__TEMP__ldwwbkwihqrpqdglcwrdylrneycegnebReentrancyGuard.huff deleted file mode 100644 index 33534b5b..00000000 --- a/src/utils/__TEMP__ldwwbkwihqrpqdglcwrdylrneycegnebReentrancyGuard.huff +++ /dev/null @@ -1,127 +0,0 @@ - -#define function state() view returns (uint256) -#define function lock() nonpayable returns () -#define function unlock() nonpayable returns () - -#define macro LOCK_WRAPPER() = takes (0) returns (0) { - LOCK() - stop -} - -#define macro UNLOCK_WRAPPER() = takes (0) returns (0) { - UNLOCK() - stop -} - -#define macro GET_STATE() = takes (0) returns (0) { - [LOCKED_SLOT] sload // [LOCKED] - 0x00 mstore // [] - 0x20 0x00 return // [] -} - -#define macro MAIN() = takes (0) returns (0) { - pc calldataload 0xE0 shr // [selector] - - dup1 __FUNC_SIG(state) eq state_jump jumpi - dup1 __FUNC_SIG(lock) eq lock_jump jumpi - dup1 __FUNC_SIG(unlock) eq unlock_jump jumpi - - DISPATCH_ERROR(0x00) - - state_jump: - GET_STATE() - - lock_jump: - LOCK_WRAPPER() - - unlock_jump: - UNLOCK_WRAPPER() -} - -/// @title Reentrancy Guard -/// @notice SPDX-License-Identifier: MIT -/// @author rayquaza7 -/// @notice Gas optimized reentrancy guard for smart contracts. -/// @notice Adapted from Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/ReentrancyGuard.sol) - -#include "./CommonErrors.huff" - -// Interface -#define function lock() nonpayable returns () -#define function unlock() nonpayable returns () - -// Constants -#define constant LOCKED_SLOT = FREE_STORAGE_POINTER() -#define constant _UNLOCKED = 0x01 -#define constant _LOCKED = 0x02 - -/// @title Lock -/// @notice Locks the contract to prevent reentrancy -#define fn LOCK() = takes (0) returns (0) { - [_LOCKED] // [0x02] - dup1 // [0x02, 0x02] - [LOCKED_SLOT] // [locked_slot, 0x02, 0x02] - sload // [locked_slot_value, 0x02, 0x02] - lt // [locked_slot_value < 0x02, 0x02] - lock jumpi - - // Otherwise revert with re-entrancy - REENTRANCY(0x00) - - lock: - [LOCKED_SLOT] sstore -} - -/// @title Unlock -/// @notice Unlocks the contract -#define fn UNLOCK() = takes (0) returns (0) { - [_UNLOCKED] [LOCKED_SLOT] sstore -} - -#define macro REENTRANCY_GUARD_MAIN() = takes (0) returns (0) { - pc calldataload 0xE0 shr - - dup1 __FUNC_SIG(lock) eq lock_jump jumpi - dup1 __FUNC_SIG(unlock) eq unlock_jump jumpi - - reentrancy_sig_no_match_found jump - - lock_jump: - LOCK() - unlock_jump: - UNLOCK() - - reentrancy_sig_no_match_found: -} - -/// @notice Test Unlocking -#define test TEST_LOCK() = takes (0) returns (0) { - // Make sure our slot is set to the UNLOCKED state - UNLOCK() - - // Lock - LOCK() - [LOCKED_SLOT] sload - - // We expect the locked slot to be set to 2 - the LOCKED state - 0x02 eq succeed jumpi - 0x00 dup1 revert - - succeed: -} - -/// @notice Test Unlocking -#define test TEST_UNLOCK() = takes (0) returns (0) { - // Make sure our slot is set to the LOCKED state - LOCK() - - // Unlock - UNLOCK() - [LOCKED_SLOT] sload - - // We expect the locked slot to be set to 1 - the UNLOCKED state - 0x01 eq succeed jumpi - 0x00 dup1 revert - - succeed: -} \ No newline at end of file diff --git a/src/utils/__TEMP__piwyyoypwjyhbfuzsxxekolsbwxgwxsdSSTORE2.huff b/src/utils/__TEMP__piwyyoypwjyhbfuzsxxekolsbwxgwxsdSSTORE2.huff deleted file mode 100644 index da214168..00000000 --- a/src/utils/__TEMP__piwyyoypwjyhbfuzsxxekolsbwxgwxsdSSTORE2.huff +++ /dev/null @@ -1,132 +0,0 @@ - -// #define function read(address, uint256) view returns (bytes memory) -// #define function read(address, uint256, uint256) view returns (bytes memory) -#define function read(address) view returns (bytes memory) -#define function write(bytes memory) nonpayable returns (address) - -#define macro SSTORE2_WRITE_WRAPPER() = takes (0) returns (0) { - SSTORE2_WRITE() // [address] - 0x00 mstore // [] - 0x20 0x00 return // [] -} - -#define macro SSTORE2_READ_WRAPPER() = takes (0) returns (0) { - 0x04 calldataload // [pointer] - SSTORE2_READ() // [data_length_in_memory] - 0x00 return // [] -} - -#define macro SSTORE2_READ_AT_WRAPPER() = takes (0) returns (0) { - 0x24 calldataload // [start] - 0x04 calldataload // [pointer, start] - SSTORE2_READ_AT() // [data_length_in_memory] - 0x00 return // [] -} - -#define macro SSTORE2_READ_BETWEEN_WRAPPER() = takes (0) returns (0) { - 0x44 calldataload // [end] - 0x24 calldataload // [start, end] - 0x04 calldataload // [pointer, start, end] - SSTORE2_READ_BETWEEN() // [data_length_in_memory] - 0x00 return // [] -} - -#define macro MAIN() = takes (0) returns (0) { - pc calldataload 0xE0 shr // [selector] - - dup1 __FUNC_SIG(write) eq write_jump jumpi - dup1 __FUNC_SIG(read) eq read_jump jumpi - dup1 __FUNC_SIG("read(address,uint256)") eq read_at_jump jumpi - dup1 __FUNC_SIG("read(address,uint256,uint256)") eq read_between_jump jumpi - - 0x00 dup1 revert - - write_jump: - SSTORE2_WRITE_WRAPPER() - - read_jump: - SSTORE2_READ_WRAPPER() - - read_at_jump: - SSTORE2_READ_AT_WRAPPER() - - read_between_jump: - SSTORE2_READ_BETWEEN_WRAPPER() -} - -/// @title SSTORE2 -/// @notice SPDX-License-Identifier: MIT -/// @author asnared -/// @notice Faster & cheaper contract key-value storage for Ethereum Contracts -/// @notice Adapted from 0xsequence/sstore2 (https://github.com/0xsequence/sstore2) - -#include "./Bytecode.huff" -#include "./CommonErrors.huff" - -#define constant TYPE_UINT_256_MAX = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff - -/// @notice Stores `_data` and returns `pointer` as key for later retrieval -/// @dev The pointer is a contract address with `_data` as code -/// @param {_data} [bytes memory] to be written -/// @return pointer Pointer to the written `_data` -#define macro SSTORE2_WRITE() = takes (0) returns (1) { - // Load the data memory pointer - 0x04 calldataload // [&_data] - dup1 0x04 add calldataload swap1 // [&_data, _data.length] - - // Create the contract creation code - CREATION_CODE_FOR() // [&_data, _data.length] - - // Deploy the contract - swap1 // [_data.length, &_data] - 0x0f add // [size, &_data] - 0x00 // [offset, size, &_data] - 0x00 // [value, offset, size, &_data] - create // [address, &_data] - - // Check that the address is non-zero - dup1 iszero iszero success jumpi // [address, &_data] - CREATE_FAILED(0x00) - success: - - // Clean the stack and return the address - swap1 pop // [address] -} - -/// @notice Reads the contents of the `_pointer` code as data, skips the first byte -/// @dev The function is intended for reading pointers generated by `write` -/// @param _pointer to be read -/// @return data read from `_pointer` contract -#define macro SSTORE2_READ() = takes (1) returns (1) { - // Input Stack: [_pointer] - // We start at 1 because the first byte are zeros to prevent the contract from being called - 0x01 // [_start, _pointer] - [TYPE_UINT_256_MAX] // [_end, _start, _pointer] - swap2 // [_pointer, _start, _end] - CODE_AT() // [code] -} - -/// @notice Reads the contents of the `_pointer` code as data, skips the first byte -/// @dev The function is intended for reading pointers generated by `write` -/// @param _pointer to be read -/// @param _start number of bytes to skip -/// @return data read from `_pointer` contract -#define macro SSTORE2_READ_AT() = takes (2) returns (1) { - // Input Stack: [_pointer, _start] - swap1 // [_start, _pointer] - [TYPE_UINT_256_MAX] // [_end, _start, _pointer] - swap2 // [_pointer, _start, _end] - CODE_AT() // [code] -} - -/// @notice Reads the contents of the `_pointer` code as data, skips the first byte -/// @dev The function is intended for reading pointers generated by `write` -/// @param _pointer to be read -/// @param _start number of bytes to skip -/// @param _end index before which to end extraction -/// @return data read from `_pointer` contract -#define macro SSTORE2_READ_BETWEEN() = takes (3) returns (1) { - // Input Stack: [_pointer, _start, _end] - CODE_AT() // [code] -} - diff --git a/src/utils/__TEMP__ppohrkhyvnxmaxjzqlkackypaopwtytiErrors.huff b/src/utils/__TEMP__ppohrkhyvnxmaxjzqlkackypaopwtytiErrors.huff deleted file mode 100644 index e04e8e5b..00000000 --- a/src/utils/__TEMP__ppohrkhyvnxmaxjzqlkackypaopwtytiErrors.huff +++ /dev/null @@ -1,303 +0,0 @@ -#define function simulateRequire() pure returns () -#define function simulateAssert() pure returns () -#define function simulateAssertEq() pure returns () -#define function simulateAssertNotEq() pure returns () -#define function simulateAssertMemEq() pure returns () -#define function simulateAssertMemNotEq() pure returns () -#define function simulateAssertStorageEq() nonpayable returns () -#define function simulateAssertStorageNotEq() nonpayable returns () -#define function simulateCompilerPanic() pure returns () -#define function simulateArithmeticOverflow() pure returns () -#define function simulateDivideByZero() pure returns () -#define function simulateInvalidEnumValue() pure returns () -#define function simulateInvalidStorageByteArray() pure returns () -#define function simulateEmptyArrayPop() pure returns () -#define function simulateArrayOutOfBounds() pure returns () -#define function simulateMemoryTooLarge() pure returns () -#define function simulateUninitializedFunctionPointer() pure returns () -#define function simulateBubbleUpIfFailed(address) view returns () - -#define constant REQUIRE_LENGTH = 0x06 -#define constant REQUIRE_STRING = 0x7265766572740000000000000000000000000000000000000000000000000000 - -#define macro MAIN() = takes (0) returns (0) { - pc calldataload 0xe0 shr - dup1 __FUNC_SIG(simulateRequire) eq simulate_require jumpi - dup1 __FUNC_SIG(simulateAssert) eq simulate_assert jumpi - dup1 __FUNC_SIG(simulateAssertEq) eq simulate_assert_eq jumpi - dup1 __FUNC_SIG(simulateAssertNotEq) eq simulate_assert_not_eq jumpi - dup1 __FUNC_SIG(simulateAssertMemEq) eq simulate_assert_mem_eq jumpi - dup1 __FUNC_SIG(simulateAssertMemNotEq) eq simulate_assert_mem_not_eq jumpi - dup1 __FUNC_SIG(simulateAssertStorageEq) eq simulate_assert_storage_eq jumpi - dup1 __FUNC_SIG(simulateAssertStorageNotEq) eq simulate_assert_storage_not_eq jumpi - dup1 __FUNC_SIG(simulateCompilerPanic) eq simulate_compiler_panic jumpi - dup1 __FUNC_SIG(simulateArithmeticOverflow) eq simulateArithmeticOverflow jumpi - dup1 __FUNC_SIG(simulateDivideByZero) eq simulateDivideByZero jumpi - dup1 __FUNC_SIG(simulateInvalidEnumValue) eq simulateInvalidEnumValue jumpi - dup1 __FUNC_SIG(simulateInvalidStorageByteArray) eq simulateInvalidStorageByteArray jumpi - dup1 __FUNC_SIG(simulateEmptyArrayPop) eq simulateEmptyArrayPop jumpi - dup1 __FUNC_SIG(simulateArrayOutOfBounds) eq simulateArrayOutOfBounds jumpi - dup1 __FUNC_SIG(simulateMemoryTooLarge) eq simulateMemoryTooLarge jumpi - dup1 __FUNC_SIG(simulateUninitializedFunctionPointer) eq simulateUninitializedFunctionPointer jumpi - dup1 __FUNC_SIG(simulateBubbleUpIfFailed) eq simulateBubbleUpIfFailed jumpi - - 0x00 0x00 revert - - simulate_require: - [REQUIRE_STRING] // [message] - [REQUIRE_LENGTH] // [message_length, message] - 0x00 // [false, message_length, message] - REQUIRE() // [] - - simulate_assert: - 0x00 // [false] - ASSERT() // [] - - simulate_assert_eq: - 0x01 0x00 // [0x00, 0x01] - ASSERT_EQ() - - simulate_assert_not_eq: - 0x00 0x00 // [0x00, 0x00] - ASSERT_NOT_EQ() - - simulate_assert_mem_eq: - 0x00 dup1 mstore - 0x01 0x20 mstore - ASSERT_MEM_EQ(0x00, 0x20) - - simulate_assert_mem_not_eq: - 0x00 dup1 mstore - 0x00 0x20 mstore - ASSERT_MEM_NOT_EQ(0x00, 0x20) - - simulate_assert_storage_eq: - 0x00 dup1 sstore - 0x01 dup1 sstore - ASSERT_STORAGE_EQ(0x00, 0x01) - - simulate_assert_storage_not_eq: - 0x00 dup1 sstore - 0x00 0x01 sstore - ASSERT_STORAGE_NOT_EQ(0x00, 0x01) - - simulate_compiler_panic: - [COMPILER_PANIC] - do_panic - jump - - simulateArithmeticOverflow: - [ARITHMETIC_OVERFLOW] - do_panic - jump - - simulateDivideByZero: - [DIVIDE_BY_ZERO] - do_panic - jump - - simulateInvalidEnumValue: - [INVALID_ENUM_VALUE] - do_panic - jump - - simulateInvalidStorageByteArray: - [INVALID_STORAGE_BYTE_ARRAY] - do_panic - jump - - simulateEmptyArrayPop: - [EMPTY_ARRAY_POP] - do_panic - jump - - simulateArrayOutOfBounds: - [ARRAY_OUT_OF_BOUNDS] - do_panic - jump - - simulateMemoryTooLarge: - [MEMORY_TOO_LARGE] - do_panic - jump - - simulateUninitializedFunctionPointer: - [UNINITIALIZED_FUNCTION_POINTER] - do_panic - jump - - simulateBubbleUpIfFailed: - 0x00 // [ret_size] - dup1 // [ret_offset, ret_size] - dup1 // [args_size, ret_offset, ret_size] - dup1 // [args_offset, args_size, ret_offst, ret_size] - dup1 // [value, args_offset, args_size, ret_offst, ret_size] - 0x04 // [addr_offset, value, args_offset, args_size, ret_offst, ret_size] - calldataload // [addr, value, args_offset, args_size, ret_offst, ret_size] - gas // [gas, addr, value, args_offset, args_size, ret_offst, ret_size] - call // [success] - BUBBLE_UP_IF_FAILED() // [] - - do_panic: - PANIC() -} - - -/// @title Errors -/// @notice SPDX-License-Identifier: MIT -/// @author jtriley.eth -/// @author clabby -/// @notice Custom error utilities. - -// https://docs.soliditylang.org/en/latest/control-structures.html?highlight=panic#panic-via-assert-and-error-via-require - -// Errors -#define error Error(string) -#define error Panic(uint256) - -// Constants -// Solidity Panic Codes -#define constant COMPILER_PANIC = 0x00 -#define constant ASSERT_FALSE = 0x01 -#define constant ARITHMETIC_OVERFLOW = 0x11 -#define constant DIVIDE_BY_ZERO = 0x12 -#define constant INVALID_ENUM_VALUE = 0x21 -#define constant INVALID_STORAGE_BYTE_ARRAY = 0x22 -#define constant EMPTY_ARRAY_POP = 0x31 -#define constant ARRAY_OUT_OF_BOUNDS = 0x32 -#define constant MEMORY_TOO_LARGE = 0x41 -#define constant UNINITIALIZED_FUNCTION_POINTER = 0x51 - -/* - -Solidity Require. Error `string` MUST be no greater than 32 bytes. - -MEMORY LAYOUT WHEN THROWN -| sig || message offset || message length || message "revert" | -0x08c379a 0000000000000000000000000000000000000000000000000000000000000020 0000000000000000000000000000000000000000000000000000000000000006 7265766572740000000000000000000000000000000000000000000000000000 - -*/ -#define macro REQUIRE() = takes (3) returns (0) { - // takes: // [condition, message_length, message] - do_not_throw // [do_not_throw_jumpdest, condition, message_length, message] - jumpi // [message_length, message] - __ERROR(Error) // [error_sig, , message_length, message] - 0x00 // [mem_ptr, error_sig, message_length, message] - mstore // [message_length, message] - 0x20 // [message_offset, message_length, message] - 0x04 // [message_offset_ptr, message_offset, message_length, message] - mstore // [message_length, message] - 0x24 // [message_length_ptr, message_length, message] - mstore // [message] - 0x44 // [message_ptr, message] - mstore // [] - 0x80 // [size] - 0x00 // [offset, size] - revert // [] - do_not_throw: // [message_length, message] - pop // [message] - pop // [] -} - -/* - -Solidity Panic. - -MEMORY LAYOUT WHEN THROWN -| sig || panic code | -0x4e487b71 0000000000000000000000000000000000000000000000000000000000000001 - -*/ -#define macro PANIC() = takes (1) returns (0) { - // takes: // [panic_code] - __ERROR(Panic) // [panic_sig, panic_code] - 0x00 // [panic_sig_offset, panic_sig, panic_code] - mstore // [panic_code] - 0x04 // [panic_code_offset, panic_code] - mstore // [] - 0x24 // [revert_size] - 0x00 // [revert_offset, revert_size] - revert // [] -} - -/* -Solidity Assert. - -MEMORY LAYOUT WHEN THROWN -| sig || assert failed panic code | -0x4e487b71 0000000000000000000000000000000000000000000000000000000000000001 - -*/ -#define macro ASSERT() = takes (1) returns (0) { - // takes: // [condition] - do_not_panic // [do_not_panic_jumpdest, condition] - jumpi // [] - [ASSERT_FALSE] // [assert_false] - PANIC() // [] - do_not_panic: // [] -} - -// Assert that two stack elements are equal -#define macro ASSERT_EQ() = { - // takes: [a, b] - eq // [a == b] - ASSERT() // [] -} - -// Assert that two stack elements are not equal -#define macro ASSERT_NOT_EQ() = { - // takes: [a, b] - eq iszero // [a != b] - ASSERT() // [] -} - -// Assert that two memory offsets contain equal words -#define macro ASSERT_MEM_EQ(ptr_a, ptr_b) = { - // takes: [] - mload // [b] - mload // [a, b] - eq // [a == b] - ASSERT() // [] -} - -// Assert that two memory offsets do not contain equal words -#define macro ASSERT_MEM_NOT_EQ(ptr_a, ptr_b) = { - // takes: [] - mload // [b] - mload // [a, b] - eq iszero // [a != b] - ASSERT() // [] -} - -// Assert that two storage slots contain equal words -#define macro ASSERT_STORAGE_EQ(slot_a, slot_b) = { - // takes: [] - sload // [b] - sload // [a, b] - eq // [a == b] - ASSERT() // [] -} - -// Assert that two storage slots do not contain equal words -#define macro ASSERT_STORAGE_NOT_EQ(slot_a, slot_b) = { - // takes: [] - sload // [b] - sload // [a, b] - eq iszero // [a != b] - ASSERT() // [] -} - -/* Bubbles up revert data if call failed. Call directly after `call`, `staticcall`, `delegatecall`. */ -#define macro BUBBLE_UP_IF_FAILED() = takes (1) returns (0) { - // takes: // [call_succeeded] - call_succeeded // [call_succeeded_jumpdest, call_succeeded] - jumpi // [] - returndatasize // [returndatasize] - 0x00 // [memory_offset, returndatasize] - returndatasize // [returndatasize, memory_offset, returndatasize] - dup2 // [returndata_offset, returndatasize, memory_offset, returndatasize] - dup3 // [memory_offset, returndata_offset, returndatasize, memory_offset, returndatasize] - returndatacopy // [memory_offset, returndatasize] - revert // [] - call_succeeded: -} diff --git a/src/utils/__TEMP__prdtsuvrwjmqtxbpjcrrcoacbfeiivquShuffling.huff b/src/utils/__TEMP__prdtsuvrwjmqtxbpjcrrcoacbfeiivquShuffling.huff deleted file mode 100644 index 74d30ae0..00000000 --- a/src/utils/__TEMP__prdtsuvrwjmqtxbpjcrrcoacbfeiivquShuffling.huff +++ /dev/null @@ -1,68 +0,0 @@ -#define function oneWayShuffle(bytes32 seed, uint256 index, uint256 count, uint256 rounds) view returns (uint256) - -#define macro SHUFFLE_WRAPPER() = takes (0) returns (0) { - 0x64 calldataload // [rounds] - 0x44 calldataload // [count, rounds] - 0x24 calldataload // [index, count, rounds] - 0x04 calldataload // [seed, index, count, rounds] - MECHS__ONE_WAY_SHUFFLE(0x60, 0x80) // [index'] - 0x00 mstore 0x20 0x00 return // [] -} - -#define macro MAIN() = takes (0) returns (0) { - pc calldataload 0xE0 shr // [selector] - - dup1 __FUNC_SIG(oneWayShuffle) eq shuffle jumpi - - 0x00 dup1 revert - - shuffle: - SHUFFLE_WRAPPER() -} - - -/// @title Shuffling -/// @notice SPDX-License-Identifier: MIT -/// @author Philogy -/// @author asnared -/// @notice Refactored algorithms for shuffling and other bitwise algorithms. -/// @notice Adapted from Ethereum Consensus Specs (https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#compute_shuffled_index) - -#include "./Address.huff" -#include "./Ternary.huff" - -#include "../math/Math.huff" - -// Constants -#define constant POS_MASK = 0xffffffff00 - -/// @notice Shuffling Algorithm -#define macro MECHS__ONE_WAY_SHUFFLE(mem1, mem2) = takes (4) returns (1) { - // Input Stack: [seed, index, index_count, iters] - // Output Stack: [index'] - - __Mechs__shuffleContinue: // [seed, index, index_count, iters] - mstore // [index, index_count, iters] - 0x20 sha3 // [seed', index, index_count, iters] - dup3 dup1 // [index_count, index_count, seed' index, index_count, iters] - dup3 mod // [pivot, index_count, seed', index, index_count, iters] - dup4 dup3 // [index_count, index, pivot, index_count, seed', index, index_count, iters] - sub add mod // [flip, seed', index, index_count, iters] - dup3 dup2 MAX() // [position, flip, seed', index, index_count, iters] - dup1 [POS_MASK] and // [masked_position, position, flip, seed', index, index_count, iters] - mstore // [position, flip, seed', index, index_count, iters] - 0x40 sha3 // [rand2, position, flip, seed', index, index_count, iters] - swap1 0xff and shr // [rand_bit_unmasked, flip, seed', index, index_count, iters] - 0x1 and // [rand_bit, flip, seed', index, index_count, iters] - swap2 swap3 swap2 // [rand_bit, flip, index, seed', index_count, iters] - NOT_TERNARY() // [index', seed', index_count, iters] - swap1 swap3 // [iters, index', index_count, seed'] - UNSAFE_SUB() swap3 // [seed', index', index_count, iters'] - - // Continue if iters > 0 - dup4 __Mechs__shuffleContinue jumpi - - // Return the index - pop swap2 pop pop // [index'] -} - diff --git a/src/utils/__TEMP__qbvbklotqjimwddbdrttqayfxbbmavfvLibBit.huff b/src/utils/__TEMP__qbvbklotqjimwddbdrttqayfxbbmavfvLibBit.huff deleted file mode 100644 index 2ee77790..00000000 --- a/src/utils/__TEMP__qbvbklotqjimwddbdrttqayfxbbmavfvLibBit.huff +++ /dev/null @@ -1,267 +0,0 @@ -#define function fls(uint256) pure returns (uint256) -#define function ffs(uint256) pure returns (uint256) -#define function popCount(uint256) pure returns (uint256) -#define function isPowOf2(uint256) pure returns (uint256) - -#define macro FLS_WRAPPER() = { - 0x04 calldataload - FLS() - - 0x00 mstore - 0x20 0x00 return -} - -#define macro FFS_WRAPPER() = { - 0x04 calldataload - FFS() - - 0x00 mstore - 0x20 0x00 return -} - -#define macro POP_COUNT_WRAPPER() = { - 0x04 calldataload - POP_COUNT() - - 0x00 mstore - 0x20 0x00 return -} - -#define macro IS_POW_OF_2_WRAPPER() = { - 0x04 calldataload - IS_POW_OF_2() - - 0x00 mstore - 0x20 0x00 return -} - -#define macro MAIN() = { - pc calldataload 0xE0 shr - dup1 __FUNC_SIG(fls) eq fls jumpi - dup1 __FUNC_SIG(ffs) eq ffs jumpi - dup1 __FUNC_SIG(popCount) eq pop_count jumpi - dup1 __FUNC_SIG(isPowOf2) eq is_pow_of_2 jumpi - - 0x00 dup1 revert - - fls: - FLS_WRAPPER() - ffs: - FFS_WRAPPER() - pop_count: - POP_COUNT_WRAPPER() - is_pow_of_2: - IS_POW_OF_2_WRAPPER() -} - - -/// @title LibBit -/// @notice SPDX-License-Identifier: MIT -/// @author Vectorized -/// @author Solady (https://github.com/Vectorized/solady/blob/main/src/utils/LibBit.sol) -/// @author Inspired by (https://graphics.stanford.edu/~seander/bithacks.html) -/// @author clabby -/// @notice Various bit-twiddling macros. - -#define constant A = 0xffffffffffffffffffffffffffffffff -#define constant B = 0xffffffffffffffff -#define constant C = 0xffffffff - -#define constant FLS_DEBRUIJN = 0x0009010a0d15021d0b0e10121619031e080c141c0f111807131b17061a05041f -#define constant FFS_DEBRUIJN = 0x00011c021d0e18031e16140f191104081f1b0d17151310071a0c12060b050a09 - -/// @dev Returns the index of the most significant bit of `x`. -/// If `x` is zero, returns 256. -#define macro FLS() = takes (1) returns (1) { - // Input stack: [x] - - dup1 iszero // [x == 0, x] - 0x08 shl // [(x == 0) << 0x08, x] - - dup2 [A] lt // [A < x, r, x] - 0x07 shl // [(A < x) << 0x07, r, x] - or // [r, x] - - dup2 dup2 shr // [x >> r, r, x] - [B] lt // [B < (x >> r), r, x] - 0x06 shl // [(B < (x >> r)) << 0x06, r, x] - or // [r, x] - - dup2 dup2 shr // [x >> r, r, x] - [C] lt // [C < (x >> r), r, x] - 0x05 shl // [(C < (x >> r)) << 0x05, r, x] - or // [r, x] - - // For the remaining 32 bits, use a De Bruijn lookup. - swap1 dup2 shr // [x >> r, r] - dup1 0x01 shr // [(x >> r) >> 0x01, x >> r, r] - or // [x, r] - - dup1 0x02 shr // [x >> 0x02, x, r] - or // [x, r] - - dup1 0x04 shr // [x >> 0x04, x, r] - or // [x, r] - - dup1 0x08 shr // [x >> 0x08, x, r] - or // [x, r] - - dup1 0x10 shr // [x >> 0x10, r] - or // [x, r] - - // Note: This does increase final code size, can shift left by 224 at runtime - // if codesize is more of a concern. - __RIGHTPAD(0x07c4acdd) // [0x07c4acdd (right padded), x, r] - mul // [x * 0x07c4acdd, r] - 0xFB shr // [(x * 0x07c4acdd) >> 0xFB, r] - [FLS_DEBRUIJN] swap1 // [(x * 0x07c4acdd) >> 0xFB, debruijn_lookup, r] - byte // [b, r] - or // [b | r] - - // Return stack: [r] -} - -/// @dev Returns the index of the least significant bit of `x`. -/// If `x` is zero, returns 256. -#define macro FFS() = takes (1) returns (1) { - // Input stack: [x] - - dup1 iszero // [x == 0, x] - 0x08 shl // [(x == 0) << 0x08, x] - - // Isolate the least significant bit. - swap1 dup1 // [x, x, r] - not 0x01 add // [~x + 1, x, r] - and // [x, r] - - swap1 dup2 // [x, r, x] - [A] lt // [A < x, r, x] - 0x07 shl // [(A < x) << 0x07, r, x] - or // [r, x] - - dup2 dup2 shr // [x >> r, r, x] - [B] lt // [B < (x >> r), r, x] - 0x06 shl // [(B < (x >> r)) << 0x06, r, x] - or // [r, x] - - dup2 dup2 shr // [x >> r, r, x] - [C] lt // [C < (x >> r), r, x] - 0x05 shl // [(C < (x >> r)) << 0x05] - or // [r, x] - - // For the remaining 32 bits, use a De Bruijn lookup. - - // Note: This does increase final code size, can shift left by 224 at runtime - // if codesize is more of a concern. - swap1 dup2 shr // [x >> r, r] - __RIGHTPAD(0x077cb531) // [0x077cb531..., x >> r, r] - mul // [(x >> r) * 0x077cb531, r] - 0xFB shr // [(x * 0x077cb531) >> 0xFB, r] - [FFS_DEBRUIJN] swap1 // [(x * 0x077cb531) >> 0xFB, debruijn_lookup, r] - byte // [b, r] - or // [b | r] - - // Return stack: [r] -} - -/// @dev Returns the number of set bits in `x`. -#define macro POP_COUNT() = takes (1) returns (1) { - // Input stack: [x] - - 0x00 not // [max, x] - dup1 dup3 lt // [is_not_max, max, x] - - swap2 // [x, max, is_not_max] - 0x03 dup3 div // [max / 0x03, x, max, is_not_max] - dup2 0x01 shr // [x >> 0x01, max / 0x03, x, max, is_not_max] - and // [(x >> 0x01) & (max / 0x03), x, max, is_not_max] - swap1 sub // [x, max, is_not_max] - - 0x05 dup3 div // [max / 0x05, x, max, is_not_max] - dup1 // [max / 0x05, max / 0x05, x, max, is_not_max] - dup3 0x02 shr // [x >> 0x02, max / 0x05, max / 0x05 x, max, is_not_max] - and // [(x >> 0x02) & (max / 0x05), max / 0x05, x, max, is_not_max] - swap2 // [max / 0x05, x, (x >> 0x02) & (max / 0x05), max, is_not_max] - and add // [x, max, is_not_max] - - 0x11 dup3 div // [max / 0x11, x, max, is_not_max] - swap1 // [x, max / 0x11, max, is_not_max] - dup1 0x04 shr // [x >> 0x04, x, max / 0x11, max, is_not_max] - add and // [x, max, is_not_max] - - swap1 0xFF // [0xFF, max, x, is_not_max] - swap1 div // [max / 0xFF, x, is_not_max] - mul // [(max / 0xFF) * x, is_not_max] - 0xF8 shr // [((max / 0xFF) * x) >> 0xF8, is_not_max] - 0x100 xor // [((max / 0xFF) * x) >> 0xF8) ^ 0x100, is_not_max] - mul // [((((max / 0xFF) * x) >> 0xF8) ^ 0x100) * is_not_max] - 0x100 xor // [(((((max / 0xFF) * x) >> 0xF8) ^ 0x100) * is_not_max) ^ 0x100] - - // Return stack: [c] -} - -/// @dev Returns 1, if the input is a power of 2. -#define macro IS_POW_OF_2() = takes (1) returns (1) { - // Input stack: [x] - - 0x01 // [1,x] - dup2 // [x,1,x] - sub // [x-1,x] - dup2 // [x,x-1,x] - and // [x & x-1,x] - swap1 // [x, x&x-1] - iszero // [x==0, x&x-1] - add // [(x==0) + (x&x-1)] - iszero // [(x==0) + (x&x-1) == 0] - - // Return stack: [c] -} - - -#define test FLS() = { - 0xFF 0x03 shl - FLS() - - 0x0a eq succeed jumpi - 0x00 dup1 revert - - succeed: -} - -#define test FFS() = { - 0xFF 0x03 shl - FFS() - - 0x03 eq succeed jumpi - 0x00 dup1 revert - - succeed: -} - -#define test POP_COUNT() = { - 0x01 dup1 - 0xFF shl or - POP_COUNT() - - 0x02 eq succeed jumpi - 0x00 dup1 revert - - succeed: -} - -#define test IS_POW_OF_2() = { - 0x05 dup1 - IS_POW_OF_2() - - 0x00 eq next jumpi - 0x00 dup1 revert - - next: - 0x08 dup1 - IS_POW_OF_2() - - 0x01 eq succeed jumpi - 0x00 dup1 revert - - succeed: -} \ No newline at end of file diff --git a/src/utils/__TEMP__qfzbthtrligkzrxhdcwizlbkonnnqqiyCalls.huff b/src/utils/__TEMP__qfzbthtrligkzrxhdcwizlbkonnnqqiyCalls.huff deleted file mode 100644 index 019625c2..00000000 --- a/src/utils/__TEMP__qfzbthtrligkzrxhdcwizlbkonnnqqiyCalls.huff +++ /dev/null @@ -1,217 +0,0 @@ - -#define function callFunc() payable returns () -#define function staticcallFunc() payable returns () -#define function callcodeFunc() payable returns () - -#define macro CALL_WRAPPER() = takes (0) returns (0) { - // Store 0xba5ed in memory - 0xba5ed dup1 0x00 mstore // [0xba5ed] - - // Static Call - CALL(0x01, 0x00, 0x01, 0x00, 0x00, 0x04, 0xFFFFFFFF) // [success, 0xba5ed] - - // Revert if call is unsuccessful - iszero iszero cont jumpi - 0x00 dup1 revert - cont: - - // Load the result - 0x00 mload // [res, 0xba5ed] - - // Compare the results and revert if unequal - eq success jumpi // [] - 0x00 dup1 revert - success: - - stop -} - -#define macro STATICCALL_WRAPPER() = takes (0) returns (0) { - // Store 0xba5ed in memory - 0xba5ed dup1 0x00 mstore // [0xba5ed] - - // Static Call - STATICCALL(0x01, 0x00, 0x01, 0x00, 0x04, 0xFFFFFFFF) // [success, 0xba5ed] - - // Revert if call is unsuccessful - iszero iszero cont jumpi - 0x00 dup1 revert - cont: - - // Load the result - 0x00 mload // [res, 0xba5ed] - - // Compare the results and revert if unequal - eq success jumpi // [] - 0x00 dup1 revert - success: - - stop -} - -#define macro CALLCODE_WRAPPER() = takes (0) returns (0) { - // TODO - - stop -} - -#define macro MAIN() = takes (0) returns (0) { - // Load the function selector - pc calldataload 0xE0 shr // [sig] - - // Match on the function selector - dup1 __FUNC_SIG(callFunc) eq call_jump jumpi // [sig] - dup1 __FUNC_SIG(staticcallFunc) eq staticcall_jump jumpi // [sig] - dup1 __FUNC_SIG(callcodeFunc) eq callcode_jump jumpi // [sig] - - 0x00 dup1 revert - - call_jump: - CALL_WRAPPER() - staticcall_jump: - STATICCALL_WRAPPER() - callcode_jump: - CALLCODE_WRAPPER() -} - - -/// @title Calls -/// @notice SPDX-License-Identifier: MIT -/// @author asnared -/// @author Franfran -/// @notice Calls is a library of utility functions for calling contracts - -/// @notice Calls a contract with the given arguments -/// @notice Returns the success of the call -/// @notice Returndata is left in memory for the caller to handle -/// @param ret_size The size of the return data -/// @param ret_offset The offset in memory to store the return data -/// @param arg_size The size of the arguments -/// @param arg_offset The offset in memory of the arguments -/// @param value The value to send with the call -/// @param to The address to call -/// @param gas The amount of gas to send with the call -#define macro CALL( - ret_size, - ret_offset, - arg_size, - arg_offset, - value, - to, - maxgas -) = takes (0) returns (1) { - // [retSize] - // [retOffset, retSize] - // [argSize, retOffset, retSize] - // [argOffset, argSize, retOffset, retSize] - // [value, argOffset, argSize, retOffset, retSize] - // [to, value, argOffset, argSize, retOffset, retSize] - // [gas, to, value, argOffset, argSize, retOffset, retSize] - call // [success] -} - -/// @notice Staticalls a contract with the given arguments -/// @notice Returns the success of the call -/// @notice Returndata is left in memory for the caller to handle -/// @dev This instructions is equivalent to CALL, except that it does not allow any state modifying instructions or sending ETH in the sub context. -/// @dev The disallowed instructions are CREATE, CREATE2, LOG0, LOG1, LOG2, LOG3, LOG4, SSTORE, SELFDESTRUCT and CALL if the value sent is not 0. -/// @dev If the size of the return data is not known, it can also be retrieved after the call with the instructions RETURNDATASIZE and RETURNDATACOPY (since the Byzantium fork). -/// @param ret_size The size of the return data -/// @param ret_offset The offset in memory to store the return data -/// @param arg_size The size of the arguments -/// @param arg_offset The offset in memory of the arguments -/// @param to The address to call -/// @param gas The amount of gas to send with the call -#define macro STATICCALL( - ret_size, - ret_offset, - arg_size, - arg_offset, - to, - maxgas -) = takes (0) returns (1) { - // [retSize] - // [retOffset, retSize] - // [argSize, retOffset, retSize] - // [argOffset, argSize, retOffset, retSize] - // [to, argOffset, argSize, retOffset, retSize] - // [gas, to, argOffset, argSize, retOffset, retSize] - staticcall // [success] -} - -/// @notice Codecalls a contract with the given arguments -/// @notice Returns the success of the call -/// @notice Returndata is left in memory for the caller to handle -/// @dev Creates a new sub context as if calling itself, but with the code of the given account. -/// @dev In particular the storage remains the same. Note that an account with no code will return success as true. -/// @dev If the size of the return data is not known, it can also be retrieved after the call with the instructions RETURNDATASIZE and RETURNDATACOPY (since the Byzantium fork). -/// @param ret_size The size of the return data -/// @param ret_offset The offset in memory to store the return data -/// @param arg_size The size of the arguments -/// @param arg_offset The offset in memory of the arguments -/// @param value The value to send with the call -/// @param to The address to call -/// @param gas The amount of gas to send with the call -#define macro CALLCODE( - ret_size, - ret_offset, - arg_size, - arg_offset, - value, - to, - maxgas -) = takes (0) returns (1) { - // [retSize] - // [retOffset, retSize] - // [argSize, retOffset, retSize] - // [argOffset, argSize, retOffset, retSize] - // [value, argOffset, argSize, retOffset, retSize] - // [to, argOffset, argSize, retOffset, retSize] - // [gas, to, argOffset, argSize, retOffset, retSize] - callcode // [success] -} - -/// @notice Test call the identity precompile -#define test TEST_CALL() = takes (0) returns (0) { - // Store 0xba5ed in memory - 0xba5ed dup1 0x00 mstore // [0xba5ed] - - // Static Call - CALL(0x01, 0x00, 0x01, 0x00, 0x00, 0x04, 0xFFFFFFFF) // [success, 0xba5ed] - - // Revert if call is unsuccessful - iszero iszero cont jumpi - 0x00 dup1 revert - cont: - - // Load the result - 0x00 mload // [res, 0xba5ed] - - // Compare the results and revert if unequal - eq success jumpi // [] - 0x00 dup1 revert - success: -} - -/// @notice Test staticcall the identity precompile -#define test TEST_STATIC_CALL() = takes (0) returns (0) { - // Store 0xba5ed in memory - 0xba5ed dup1 0x00 mstore // [0xba5ed] - - // Static Call - STATICCALL(0x01, 0x00, 0x01, 0x00, 0x04, 0xFFFFFFFF) // [success, 0xba5ed] - - // Revert if call is unsuccessful - iszero iszero cont jumpi - 0x00 dup1 revert - cont: - - // Load the result - 0x00 mload // [res, 0xba5ed] - - // Compare the results and revert if unequal - eq success jumpi // [] - 0x00 dup1 revert - success: -} - diff --git a/src/utils/__TEMP__rrvaaiimcokotvnwlrlotlmzautjwxvsMulticallable.huff b/src/utils/__TEMP__rrvaaiimcokotvnwlrlotlmzautjwxvsMulticallable.huff deleted file mode 100644 index 58569a85..00000000 --- a/src/utils/__TEMP__rrvaaiimcokotvnwlrlotlmzautjwxvsMulticallable.huff +++ /dev/null @@ -1,233 +0,0 @@ -#define function multicall(bytes[] calldata) payable returns (bytes[] memory) -#define function call1() view returns (uint256) -#define function call2() view returns (uint256) -#define function call3() view returns (uint256) -#define function returnsTuple(uint256, uint256) view returns (uint256, uint256) -#define function returnsStr(string) view returns (string) -#define function returnsSender() view returns (address) -#define function pay() payable returns (uint256) -#define function paid() view returns (uint256) -#define function revertsNoMsg() view returns () -#define function revertsMsg() view returns () - -#define constant PAID_SLOT = FREE_STORAGE_POINTER() - -#define macro CALL_1() = takes (0) returns (0) { - 0x11 0x00 mstore - 0x20 0x00 return -} - -#define macro CALL_2() = takes (0) returns (0) { - 0x22 0x00 mstore - 0x20 0x00 return -} - -#define macro CALL_3() = takes (0) returns (0) { - 0x33 0x00 mstore - 0x20 0x00 return -} - -#define macro RETURNS_TUPLE() = takes (0) returns (0) { - 0x04 calldataload // [x] - 0x00 mstore // [] - 0x24 calldataload // [y] - 0x20 mstore // [] - 0x40 0x00 return -} - -#define macro RETURNS_STR() = takes (0) returns (0) { - 0x24 calldataload // [str_len] - 0x40 add // [str_len + 0x40] - dup1 // [str_len + 0x40, str_len + 0x40] - 0x04 // [0x04, str_len + 0x40, str_len + 0x40] - 0x00 // [0x00, 0x04, str_len + 0x40, str_len + 0x40] - calldatacopy // [str_len + 0x40] - 0x00 return -} - -#define macro RETURNS_SENDER() = takes (0) returns (0) { - caller // [msg.sender] - 0x00 mstore // [] - 0x20 0x00 return -} - -#define macro PAY() = takes (0) returns (0) { - [PAID_SLOT] sload // [paid] - callvalue add // [paid + callvalue] - [PAID_SLOT] sstore // [] - 0x00 dup1 return -} - -#define macro PAID() = takes (0) returns (0) { - [PAID_SLOT] sload // [paid] - 0x00 mstore // [] - 0x20 0x00 return -} - -#define macro REVERTS_NO_MSG() = takes (0) returns (0) { - 0x00 dup1 revert -} - -#define macro REVERTS_MSG() = takes (0) returns (0) { - 0x5465737420526576657274000000000000000000000000000000000000000000 - 0x00 mstore - 0x0B 0x00 revert -} - -#define macro MAIN() = takes (0) returns (0) { - pc calldataload 0xE0 shr - dup1 __FUNC_SIG(multicall) eq multicall jumpi - dup1 __FUNC_SIG(call1) eq call_one jumpi - dup1 __FUNC_SIG(call2) eq call_two jumpi - dup1 __FUNC_SIG(call3) eq call_three jumpi - dup1 __FUNC_SIG(returnsTuple) eq returns_tuple jumpi - dup1 __FUNC_SIG(returnsStr) eq returns_str jumpi - dup1 __FUNC_SIG(returnsSender) eq returns_sender jumpi - dup1 __FUNC_SIG(pay) eq pay jumpi - dup1 __FUNC_SIG(paid) eq paid jumpi - dup1 __FUNC_SIG(revertsNoMsg) eq revert_no_msg jumpi - dup1 __FUNC_SIG(revertsMsg) eq revert_msg jumpi - - 0x00 dup1 revert - - multicall: - MULTICALL() - call_one: - CALL_1() - call_two: - CALL_2() - call_three: - CALL_3() - returns_tuple: - RETURNS_TUPLE() - returns_str: - RETURNS_STR() - returns_sender: - RETURNS_SENDER() - pay: - PAY() - paid: - PAID() - revert_no_msg: - REVERTS_NO_MSG() - revert_msg: - REVERTS_MSG() -} - -/// @title Multicallable -/// @notice SPDX-License-Identifier: MIT -/// @author clabby -/// @notice Enables a single call to call multiple methods within a contract. -/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/Multicallable.sol) -/// @author Adapted from Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/Multicallable.sol) - -// Calldata -#define constant DATA_LEN = 0x24 -#define constant DATA_OFFSET = 0x44 -// Memory -#define constant RES = 0x20 -#define constant RES_OFF = 0x40 - -/// @notice Multicall function entry point. -/// @dev This macro should be placed alone under a function selector's jump label. -/// -/// Expected calldata: `bytes[]` containing valid ABI-encoded function calls -/// as elements. -/// -/// Note: this macro only allows for multicalling functions that are within -/// the contract it is invoked in. -#define macro MULTICALL() = takes (0) returns (0) { - // Input stack: [] - - // Store pointer to array contents @ 0x00 - 0x20 0x00 mstore // [] - - [DATA_LEN] // [data_len_ptr] - calldataload // [data_len] - - // Only continue if data length is > 0 - dup1 continue jumpi - - // Return blank bytes array - 0x40 0x00 return - - continue: - - dup1 // [data_len, data_len] - [RES] // [res_ptr, data_len, data_len] - mstore // [data_len] - - [RES_OFF] // [results_offset, data_len] - - // Copy the offsets from calldata into memory. - swap1 // [data_len, results_offset] - 0x05 shl // [data_len * 0x20, results_offset] - dup1 // [data_len * 0x20, data_len * 0x20, results_offset] - [DATA_OFFSET] // [data_offset, data_len * 0x20, data_len * 0x20, results_offset] - dup4 // [results_offset, data_offset, data_len * 0x20, data_len * 0x20, results_offset] - calldatacopy // [data_len * 0x20, results_offset] - - dup2 add // [mem_ptr, results_offset] - dup1 // [data_end, mem_ptr, results_offset] - loop: - // The offset of the current bytes in the calldata. - dup3 // [results_offset, data_end, mem_ptr, results_offset] - mload // [result, data_end, mem_ptr, results_offset] - [DATA_OFFSET] // [0x44, result, data_end, mem_ptr, results_offset] - add // [o, data_end, mem_ptr, results_offset] - - // Copy the current bytes from calldata to the memory. - dup1 // [o, o, data_end, mem_ptr, results_offset] - calldataload // [cur_bytes_len, o, data_end, mem_ptr, results_offset] - dup2 0x20 add // [o + 0x20, cur_bytes_len, o, data_end, mem_ptr, results_offset] - dup5 // [mem_ptr, o + 0x20, cur_bytes_len, o, data_end, mem_ptr, results_offset] - calldatacopy // [o, data_end, mem_ptr, results_offset] - - calldataload // [cur_bytes_len, data_end, mem_ptr, results_offset] - 0x00 dup1 // [0x00, 0x00, cur_bytes_len, data_end, mem_ptr, results_offset] - swap2 // [cur_bytes_len, 0x00, 0x00, data_end, mem_ptr, results_offset] - dup5 // [mem_ptr, cur_bytes_len, 0x00, 0x00, data_end, mem_ptr, results_offset] - address // [self_addr, mem_ptr, cur_bytes_len, 0x00, 0x00, data_end, mem_ptr, results_offset] - gas // [gas, self_addr, mem_ptr, cur_bytes_len, 0x00, 0x00, data_end, mem_ptr, results_offset] - delegatecall // [call_result, data_end, mem_ptr, results_offset] - - // Bubble up the revert if the delegatecall reverts - iszero fail jumpi // [data_end, mem_ptr, results_offset] - - // Increment `results_offset` by 0x20 - 0x40 dup3 sub // [mem_ptr - 0x40, data_end, mem_ptr, results_offset] - dup4 mstore // [data_end, mem_ptr, results_offset] - dup3 0x20 add // [results_offset + 0x20, data_end, mem_ptr, results_offset] - swap3 pop // [data_end, mem_ptr, results_offset] - - // Append the `returndatasize()`, and the return data. - returndatasize // [ret_data_size, data_end, mem_ptr, results_offset] - dup3 // [mem_ptr, ret_data_size, data_end, mem_ptr, results_offset] - mstore // [data_end, mem_ptr, results_offset] - returndatasize // [ret_data_size, data_end, mem_ptr, results_offset] - 0x00 // [0x00, ret_data_size, data_end, mem_ptr, results_offset] - dup4 0x20 add // [mem_ptr + 0x20, 0x00, ret_data_size, data_end, mem_ptr, results_offset] - returndatacopy // [data_end, mem_ptr, results_offset] - - // Advance the `memPtr` by `returndatasize() + 0x20`, - // rounded up to the next multiple of 32. - 0xffffffffffffffe0 - 0x3f // [0x3f, 0xf..e0, data_end, mem_ptr, results_offset] - returndatasize // [ret_data_size, 0x3f, 0xf..e0, data_end, mem_ptr, results_offset] - dup5 add // [mem_ptr + ret_data_size, 0x3f, 0xf..e0, data_end, mem_ptr, results_offset] - add and // [(mem_ptr + ret_data_size + 0x3f) & 0xf..e0, data_end, mem_ptr, results_offset] - swap2 pop // [data_end, mem_ptr, results_offset] - - // Continue loop if results_offset < data_end - dup1 dup4 lt // [results_offset < data_end, data_end, mem_ptr, results_offset] - loop jumpi // [data_end, mem_ptr, results_offset] - - swap1 // [mem_ptr, data_end, results_offset] - 0x00 // [ret_mem_ptr, mem_ptr, data_end, results_offset] - return - fail: - returndatasize // [ret_data_size, data_end, mem_ptr, results_offset] - 0x00 dup1 // [0x00, 0x00, ret_data_size, data_end, mem_ptr, results_offset] - returndatacopy // [ret_data_size, data_end, mem_ptr, results_offset] - returndatasize 0x00 revert -} \ No newline at end of file diff --git a/src/utils/__TEMP__ryraejdcasobgumhdtbwarjszpnlvasmECDSA.huff b/src/utils/__TEMP__ryraejdcasobgumhdtbwarjszpnlvasmECDSA.huff deleted file mode 100644 index be184d44..00000000 --- a/src/utils/__TEMP__ryraejdcasobgumhdtbwarjszpnlvasmECDSA.huff +++ /dev/null @@ -1,305 +0,0 @@ -#define function recoverCd(bytes32, bytes calldata) view returns (address) -#define function recoverShortSig(bytes32, bytes32, bytes32) view returns (address) -#define function recoverVRSSig(bytes32, bytes32, bytes32, bytes32) view returns (address) -#define function toEthSignedMessageHash(bytes32) view returns (bytes32) -#define function toEthSignedMessageHashDyn(bytes) view returns (bytes32) - -#define macro RECOVER_CD_WRAPPER() = { - RECOVER_CD_SIG(0x04, 0x64) // [result] - 0x00 mstore // [] - 0x20 0x00 return -} - -#define macro RECOVER_SHORT_SIG_WRAPPER() = { - 0x04 calldataload // [hash] - 0x24 calldataload // [r, hash] - 0x44 calldataload // [vs, r, hash] - RECOVER_SHORT_SIG() // [result] - 0x00 mstore // [] - 0x20 0x00 return -} - -#define macro RECOVER_VRS_SIG_WRAPPER() = { - 0x64 calldataload // [s] - 0x44 calldataload // [r, s] - 0x24 calldataload // [v, r, s] - 0x04 calldataload // [hash, v, r, s] - RECOVER_VRS_SIG() // [result] - 0x00 mstore // [] - 0x20 0x00 return -} - -#define macro TO_ETH_SIGNED_MSG_HASH_WRAPPER() = { - 0x04 calldataload // [hash] - TO_ETH_SIGNED_MSG_HASH() // [result] - 0x00 mstore // [] - 0x20 0x00 return -} - -#define macro TO_ETH_SIGNED_MSG_HASH_DYN_WRAPPER() = { - 0x24 calldataload // [len(s)] - 0x20 add // [len(s) + 0x20] - 0x24 0x60 calldatacopy // [] - TO_ETH_SIGNED_MSG_HASH_DYN(0x60) // [result] - 0x00 mstore // [] - 0x20 0x00 return -} - -#define macro MAIN() = { - pc calldataload 0xE0 shr - dup1 __FUNC_SIG(recoverCd) eq recover_cd jumpi - dup1 __FUNC_SIG(recoverShortSig) eq recover_short_sig jumpi - dup1 __FUNC_SIG(recoverVRSSig) eq recover_vrs_sig jumpi - dup1 __FUNC_SIG(toEthSignedMessageHash) eq to_eth_signed_msg_hash jumpi - dup1 __FUNC_SIG(toEthSignedMessageHashDyn) eq to_eth_signed_msg_hash_dyn jumpi - - // Revert if no function selectors match - 0x00 dup1 revert - - // Fn dispatch - recover_cd: - RECOVER_CD_WRAPPER() - recover_short_sig: - RECOVER_SHORT_SIG_WRAPPER() - recover_vrs_sig: - RECOVER_VRS_SIG_WRAPPER() - to_eth_signed_msg_hash: - TO_ETH_SIGNED_MSG_HASH_WRAPPER() - to_eth_signed_msg_hash_dyn: - TO_ETH_SIGNED_MSG_HASH_DYN_WRAPPER() -} - - -/// @title ECDSA -/// @notice Gas optimized ECDSA wrapper. -/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/ECDSA.sol) -/// @author Modified from Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/ECDSA.sol) -/// @author Modified from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/cryptography/ECDSA.sol) -/// @author clabby - -//////////////////////////////////////////////////////////////// -// CONSTANTS // -//////////////////////////////////////////////////////////////// - -/// @dev The number which `s` must not exceed in order for the signature to be non-malleable. -#define constant MALLEABILITY_THRESHOLD = 0x7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0 - -/// @dev Ethereum Signed Message header. Used in `TO_ETH_SIGNED_MSG_HASH` -#define constant SIG_HEADER = 0x0000000019457468657265756d205369676e6564204d6573736167653a0a3332 - -/// @dev Ethereum Signed Message header. Used in `TO_ETH_SIGNED_MSG_HASH_DYN` -#define constant SIG_HEADER_DYN = 0x00000000000019457468657265756d205369676e6564204d6573736167653a0a - -//////////////////////////////////////////////////////////////// -// RECOVERY OPERATIONS // -//////////////////////////////////////////////////////////////// - -/// @dev Recovers the signer's address from a message digest `hash`, -/// and the `signature`. -/// -/// This macro does NOT accept EIP-2098 short form signatures. -/// Use `recover(bytes32 hash, bytes32 r, bytes32 vs)` for EIP-2098 -/// short form signatures instead. -/// -/// WARNING! -/// The result will be the zero address upon recovery failure. -/// As such, it is extremely important to ensure that the address which -/// the result is compared against is never zero. -/// @notice The `sig_ptr` param must point to the *offset* of the signature data -/// in calldata. -#define macro RECOVER_CD_SIG(hash_ptr, sig_ptr) = returns (1) { - // Input stack: [] - - calldataload // [hash] - 0x20 sub // [sig_len_ptr, hash] - calldataload // [len(signature), hash] - - // If len(signature) != 65, jump to `zero`. - 0x41 eq iszero // [len(signature) != 0x41, hash] - zero jumpi // [hash] - - // Copy `r` and `s` from the calldata - 0x40 dup2 // [0x40, sig_ptr, 0x40, hash] - calldatacopy // [hash] - - // If `s` is not in lower half order, such that the signature is malleable, - // jump to `zero`. - [MALLEABILITY_THRESHOLD] // [malleability_threshold, hash] - 0x60 mload // [s, malleability_threshold, hash] - gt // [s > MALLEABILITY_THRESHOLD, hash] - zero jumpi // [hash] - - // Store `hash` in scratch space @ 0x00 - 0x00 mstore // [] - // Compute `v` and store it in scratch space @ 0x20 - 0x40 add // [0x40 + sig_ptr] - calldataload // [cd] - 0x00 byte // [v] - 0x20 mstore // [] - - 0x20 0x40 0x80 0x00 0x01 // [0x01, 0x00, 0x80, 0x40, 0x20] - gas staticcall pop // [] - - // Restore the zero slot - 0x00 0x60 mstore // [] - - // `returndatasize` will be `0x20` upon success, and `0x00` otherwise. - returndatasize 0x60 sub // [0x60 - returndatasize] - mload // [result] - end jump // [result] - - zero: - pop 0x00 // [0x00] - end: - - // Return stack: [result] -} - -/// @dev Recovers the signer's address from a message digest `hash`, -/// and the EIP-2098 short form signature defined by `r` and `vs`. -/// -/// This function only accepts EIP-2098 short form signatures. -/// See: https://eips.ethereum.org/EIPS/eip-2098 -/// -/// To be honest, I do not recommend using EIP-2098 signatures -/// for simplicity, performance, and security reasons. Most if not -/// all clients support traditional non EIP-2098 signatures by default. -/// As such, this method is intentionally not fully inlined. -/// It is merely included for completeness. - Vectorized -/// -/// WARNING! -/// The `result` will be the zero address upon recovery failure. -/// As such, it is extremely important to ensure that the address which -/// the `result` is compared against is never zero. -#define macro RECOVER_SHORT_SIG() = takes (3) returns (1) { - // Input stack: [vs, r, hash] - - dup1 0xFF shr 0x1B add // [v, vs, r, hash] - swap1 // [vs, v, r, hash] - 0x01 shl 0x01 shr // [s, v, r, hash] - swap3 // [hash, v, r, s] - RECOVER_VRS_SIG() // [result] - - // Return stack: [result] -} - -/// @dev Recovers the signer's address from a message digest `hash`, -/// and the signature defined by `v`, `r`, `s`. -/// -/// WARNING! -/// The `result` will be the zero address upon recovery failure. -/// As such, it is extremely important to ensure that the address which -/// the `result` is compared against is never zero. -#define macro RECOVER_VRS_SIG() = takes (4) returns (1) { - // Input stack: [hash, v, r, s] - - // If `s` is not in lower half order, such that the signature is malleable, - // jump to `zero`. - [MALLEABILITY_THRESHOLD] // [malleability_threshold, hash, v, r, s] - dup5 gt // [s > malleability_threshold, hash, v, r, s] - zero jumpi // [hash, v, r, s] - - 0x00 mstore // [v, r, s] - 0x20 mstore // [r, s] - 0x40 mstore // [s] - 0x60 mstore // [] - - 0x20 0x40 0x80 0x00 0x01 // [0x01, 0x00, 0x80, 0x40, 0x20] - gas staticcall pop // [] - - // Restore the zero slot - 0x00 0x60 mstore // [] - returndatasize 0x60 sub // [0x60 - returndatasize] - mload // [result] - end jump - - zero: - pop pop pop pop 0x00 // [0x00] - end: - - // Return stack: [result] -} - -/// @dev Returns an Ethereum Signed Message, created from a `hash`. -/// This produces a hash corresponding to the one signed with the -/// [`eth_sign`](https://eth.wiki/json-rpc/API#eth_sign) -/// JSON-RPC method as part of EIP-191. -#define macro TO_ETH_SIGNED_MSG_HASH() = takes (1) returns (1) { - // Input stack: [hash] - - // Store in scratch space for hashing. - 0x20 mstore // [] - [SIG_HEADER] 0x00 mstore // [] - - 0x3c 0x04 sha3 // [result] - - // Return stack: [result] -} -/// @dev Returns an Ethereum Signed Message, created from `s`. -/// This produces a hash corresponding to the one signed with the -/// [`eth_sign`](https://eth.wiki/json-rpc/API#eth_sign) -/// JSON-RPC method as part of EIP-191. -/// -/// @dev The msg *must* be stored at a memory offset >= 0x60. Otherwise, -/// the logic that restores the 128 bytes before the `msg_ptr` will -/// underflow, causing a revert due to excessive memory expansion. -#define macro TO_ETH_SIGNED_MSG_HASH_DYN(msg_ptr) = returns (1) { - // Input stack: [] - - // We need at most 128 bytes for Ethereum signed message header. - // The max length of the ASCII reprenstation of a uint256 is 78 bytes. - // The length of "\x19Ethereum Signed Message:\n" is 26 bytes (i.e. 0x1a). - // The next multiple of 32 above 78 + 26 is 128 (i.e. 0x80). - - // Instead of allocating, we temporarily copy the 128 bytes before the - // start of `msg` data to some variables. - // [msg_ptr] - 0x40 dup2 sub mload // [m2, msg_ptr] - 0x20 dup3 sub mload // [m1, m2, msg_ptr] - 0x60 dup4 sub mload // [m3, m1, m2, msg_ptr] - swap3 // [msg_ptr, m1, m2, m3] - dup1 mload // [len(msg), msg_ptr, m1, m2, m3] - - swap1 0x20 add // [ptr, len(msg), m1, m2, m3] - dup2 dup2 add // [end, ptr, len(msg), m1, m2, m3] - swap1 // [ptr, end, len(msg), m1, m2, m3] - dup3 swap1 // [ptr, temp, end, len(msg), m1, m2, m3] - - loop: - 0x01 swap1 sub // [ptr - 0x01, temp, end, len(msg), m1, m2, m3] - 0x0A dup3 mod // [temp % 0x0A, ptr, temp, end, len(msg), m1, m2, m3] - 0x30 add // [(temp % 0x0A) + 0x30, ptr, temp, end, len(msg), m1, m2, m3] - dup2 mstore8 // [ptr, temp, end, len(msg), m1, m2, m3] - 0x0A dup3 div // [temp / 0x0A, ptr, temp, end, len(msg), m1, m2, m3] - swap2 pop // [ptr, temp, end, len(msg), m1, m2, m3] - - // Continue loop if temp != 0 - dup2 loop jumpi // [ptr, temp, end, len(msg), m1, m2, m3] - - // Copy the header into memory. - [SIG_HEADER_DYN] // [sig_header, ptr, temp, end, len(msg), m1, m2, m3] - 0x20 dup3 sub // [ptr - 0x20, sig_header, ptr, temp, end, len(msg), m1, m2, m3] - mstore // [ptr, temp, end, len(msg), m1, m2, m3] - swap1 pop // [ptr, end, len(msg), m1, m2, m3] - - // Compute the keccak256 hash of the memory. - 0x1A swap1 sub // [ptr - 0x1A, end, len(msg), m1, m2, m3] - dup1 // [ptr - 0x1A, ptr - 0x1A, end, len(msg), m1, m2, m3] - swap2 sub // [end - (ptr - 0x1A), ptr - 0x1A, len(msg), m1, m2, m3] - swap1 // [ptr - 0x1A, end - (ptr - 0x1A), len(msg), m1, m2, m3] - sha3 // [result, len(msg), m1, m2, m3] - - // Restore the previous memory. - // TODO: Can keep msg_ptr on stack here and dup rather than pushing it - // 4 times. - swap4 // [m3, len(msg), m1, m2, result] - 0x60 sub // [sig_ptr - 0x60, m3, len(msg), m1, m2, result] - mstore // [len(msg), m1, m2, result] - mstore // [m1, m2, result] - 0x20 sub // [sig_ptr - 0x20, m1, m2, result] - mstore // [m2, result] - 0x40 sub // [sig_ptr - 0x40, m2, result] - mstore // [result] - - // Return stack: [result] -} diff --git a/src/utils/__TEMP__sjmfwvdxpickfrbtnbbaudfvqefkatoiRefunded.huff b/src/utils/__TEMP__sjmfwvdxpickfrbtnbbaudfvqefkatoiRefunded.huff deleted file mode 100644 index 6dde1042..00000000 --- a/src/utils/__TEMP__sjmfwvdxpickfrbtnbbaudfvqefkatoiRefunded.huff +++ /dev/null @@ -1,97 +0,0 @@ - -#define function refundedCall() payable returns () -#define function nonRefundedCall() payable returns () - -#define event NonRefundedCall(address) - -#define macro MAIN() = takes (0) returns (0) { - pc calldataload 0xe0 shr - - dup1 __FUNC_SIG(refundedCall) eq refunded_call jumpi - dup1 __FUNC_SIG(nonRefundedCall) eq non_refunded_call jumpi - - 0x00 dup1 revert - - refunded_logic: - caller __EVENT_HASH(NonRefundedCall) 0x00 0x00 log2 - __Refund_Return_Dest jump - - refunded_call: - REFUNDED(refunded_logic) - stop - non_refunded_call: - caller __EVENT_HASH(NonRefundedCall) 0x00 0x00 log2 - stop -} - -/// @title Refunded -/// @notice SPDX-License-Identifier: MIT -/// @author asnared -/// @notice Efficient gas refunds distributed through a modifier -/// @notice Adapted from Zolidity (https://github.com/z0r0z/zolidity/blob/main/src/utils/Refunded.sol) - -#include "./Errors.huff" -#include "./ReentrancyGuard.huff" - -/// @notice The base cost of refunding -#define constant BASE_COST = 0x6359 // 25433 - -/// @notice The maximum amount of gas that can be refunded -#define constant GAS_PRICE_MAX = 0x9502F9000 // 4e10 - -// Refunded custom errors -#define constant MAX_GAS_ERROR = 0x4d41585f47415300000000000000000000000000000000000000000000000000 -#define constant MAX_GAS_LENGTH = 0x07 - -/// @notice Refunds contract calls up to a maximum of 4e10 gas -/// @notice Modified functions over 21k gas benefit most from a refund -#define macro REFUNDED(dest) = takes (0) returns (0) { - // Get the starting amount of gas - gas // [gasLeft] - - // Prevent Reentrancy - LOCK() // [gasLeft] - - basefee [GAS_PRICE_MAX] add // [currMaxGas, gasLeft] - gasprice gt iszero // [!(gasPrice > currMaxGas), gasLeft] - __Safe_Gas_Refund__j jumpi // [gasLeft] - MAX_GAS(0x00) - - __Safe_Gas_Refund__j: - - // The below attempts to mimic `_;` using a jump - // NOTE: This must jump back to `__Refund_Return_Dest` to complete the refund - jump - __Refund_Return_Dest: - - // Calculate refund amount - gas swap1 sub // [gasUsed] - [BASE_COST] add // [gasUsed + BASE_COST] - gasprice mul // [(gasUsed + BASE_COST) * gasPrice] - - // Refund the gas to origin - 0x00 // [retOffset, value] - 0x00 // [argSize, retOffset, value] - 0x00 // [argOffset, argSize, retOffset, value] - 0x00 // [retSize, argOffset, argSize, retOffset, value] - swap4 // [value, argOffset, argSize, retOffset, retSize] - origin // [to, value, argOffset, argSize, retOffset, retSize] - gas // [gas, to, value, argOffset, argSize, retOffset, retSize] - call - iszero iszero __Refund_Successful__j jumpi - 0x00 dup1 revert - - // The refund was successful! - __Refund_Successful__j: - - // Finally, unlock the guard - UNLOCK() -} - -/// @notice Reverts with an "MAX_GAS" message if the condition is false -#define macro MAX_GAS(condition) = takes (0) returns (0) { - [MAX_GAS_ERROR] // ["MAX_GAS"] - [MAX_GAS_LENGTH] // [7 (length), "MAX_GAS"] - // [condition, 7 (length), "MAX_GAS"] - REQUIRE() // [] -} \ No newline at end of file diff --git a/src/utils/__TEMP__sqowhqjsqxheosskvfeygpuobkhcslnvMerkleDistributor.huff b/src/utils/__TEMP__sqowhqjsqxheosskvfeygpuobkhcslnvMerkleDistributor.huff deleted file mode 100644 index 867e8160..00000000 --- a/src/utils/__TEMP__sqowhqjsqxheosskvfeygpuobkhcslnvMerkleDistributor.huff +++ /dev/null @@ -1,247 +0,0 @@ - -#define macro CONSTRUCTOR() = takes (0) returns (0) { - MERKLE_DISTRIBUTOR_CONSTRUCTOR() -} - -#define macro MAIN() = takes (0) returns (0) { - pc calldataload 0xE0 shr - MERKLE_DISTRIBUTOR_MAIN() - 0x00 dup1 revert -} - - -/// @title Merkle Distributor -/// @notice SPDX-License-Identifier: MIT -/// @author Ben Leimberger -/// @author Magna -/// @author asnared -/// @notice Minimal, gas efficient Merkle Distributor implementation - - -// Imports -#include "./CommonErrors.huff" -#include "./MerkleProofLib.huff" -#include "./Address.huff" -#include "./ERC20Transfer.huff" - -// Interface -#define function claim(uint256,address,uint256,bytes32[]) nonpayable returns () - -#define function getMerkleRoot() view returns (bytes32) -#define function getTokenAddress() view returns (address) -#define function isClaimed(uint256) view returns (bool) - -// Storage Slots -#define constant CLAIMED_BIT_MAP_SLOT = FREE_STORAGE_POINTER() // 0x00 -#define constant TOKEN_ADDR_SLOT = FREE_STORAGE_POINTER() // 0x01 -#define constant MERKLE_ROOT_SLOT = FREE_STORAGE_POINTER() // 0x02 - -// Errors -#define error TransferError(string) -#define error ClaimedError(string) -#define error ProofError(string) - - -/// @notice Get Merkle Root -/// @notice Entry point for: getMerkleRoot() -/// @dev Fetches merkle root from storage slot -/// @param {calldata} [] -/// @return {return} [bytes32 root] -#define macro GET_MERKLE_ROOT() = takes (0) returns (0) { - // Load value from storage - [MERKLE_ROOT_SLOT] sload // [merkle_root] - - // Store value in memory - 0x00 mstore // [] - - // Return value - 0x20 0x00 return // [] -} - -/// @notice Get Token Address -#define macro GET_TOKEN_ADDR() = takes (0) returns (0) { - // Load value from storage - [TOKEN_ADDR_SLOT] sload // [token_addr] - - // Store value in memory - 0x00 mstore // [] - - // Return value - 0x20 0x00 return // [] -} - - -/// Is Claimed -/// @notice Entry point for: isClaimed(uint256) -/// @dev Check if index is claimed -/// @param {calldata} [uint256 index] -/// @return {return} [bytes32 root] -#define macro IS_CLAIMED() = takes (0) returns (0) { - // Load first argument from calldata - 0x04 calldataload // [index] - - // Utility macro - __UTIL_IS_CLAIMED() // [isEqual] - - // store result in memory - 0x00 mstore // [] - 0x20 0x00 return -} - -/// @dev stores result in 0x00 to 0x20 memory slot -#define macro __UTIL_IS_CLAIMED() = takes (1) returns (1) { - // Stack input: // [arg0] - // Stack output: // [isEqual] - // index / 256 - 0x100 dup2 div // [index] - - __UTIL_GENERATE_MAPPING_KEY() // [key(claimed[index]), arg0] - - // Load mapping key - sload // [claimed[index], arg0] - - // index % 256 [claimed[index], arg0] - 0x1 0x100 dup4 mod shl // [mask, claimed[index], arg0] - dup1 swap2 dup2 and // [masked, mask, claimed[index], arg0] - eq // [isEqual, claimed[index], arg0] - swap2 pop pop // [isEqual] -} - - -/// @notice Set as claimed -#define macro __UTIL_SET_CLAIMED() = takes (1) returns (0) { - // Stack input: // [arg0] - - // index / 256 - 0x100 dup2 div // [index, arg0] - - __UTIL_GENERATE_MAPPING_KEY() // [key(claimed[index]), arg0] - - // Load mapping key - dup1 sload // [claimed[index], key(claimed[index]), arg0] - - // index % 256 [claimed[index], key(claimed[index]), arg0] - 0x1 0x100 dup5 mod shl // [mask, claimed[index], key(claimed[index]), arg0] - or // [masked, key(claimed[to]), arg0] - - // Update - swap1 sstore pop // [] -} - -/// @notice Creates a mapping key from an index -#define macro __UTIL_GENERATE_MAPPING_KEY() = takes (1) returns (1) { - // Stack input: [index] - // Stack output: [key(claimed[index])] - 0x00 mstore // [] - [CLAIMED_BIT_MAP_SLOT] 0x20 mstore // [] - - // key(claimed[index]) = keccak256(index . claimedBitMapSlot) - 0x40 0x00 sha3 // [key(claimed[index])] -} - -/// @notice Claim -/// @notice Entry point for: claim(uint256,address,uint256,bytes[]) -/// @dev Claim distribution with proof -/// @param {calldata} [uint256 index, address account, uint256 amount, bytes[] proof] -/// @return {return} [] -#define macro CLAIM() = takes (0) returns (0) { - // Preload merkle root - [MERKLE_ROOT_SLOT] sload // [root] - - // Load arguments from calldata - 0x44 calldataload // [amount, root] - 0x24 calldataload MASK_ADDRESS() // [account, amount, root] - 0x04 calldataload // [index, account, amount, root] - - // Check if an index is claimed - dup1 __UTIL_IS_CLAIMED() // [isClaimed, index, account, amount, root] - iszero cont jumpi // [index, account, amount, root] - ALREADY_CLAIMED(0x00) - cont: - - // EncodePacked - // [ 32 bytes | 20 bytes | 32 bytes ] = 84 bytes - 0x00 mstore // [account, amount, root] - 0x60 shl // [account << 12, amount, root] - 0x20 mstore // [amount, root] - 0x34 mstore // [root] - 0x54 0x00 sha3 // [leaf, root] - - // Verify merkle proof - 0x64 calldataload 0x4 add // [&proof_length, leaf, root] - - // Required() - VERIFY_PROOF() // [isProven] - verified jumpi // [] - INVALID_PROOF(0x00) - verified: - - // Mark it claimed - 0x04 calldataload // [arg0] - __UTIL_SET_CLAIMED() // [] - - // Load other calldata arguments - [TOKEN_ADDR_SLOT] sload // [getter_addr] - 0x44 calldataload // [amount, getter_addr] - 0x24 calldataload // [address_raw, amount, getter_addr] - MASK_ADDRESS() // [address, amount, getter_addr] - - // Send the token - ERC20_TRANSFER() - - // Finish Execution - stop -} - -/// @notice Constructor -/// @param address The address of the token to distribute -/// @param merkleRoot The merkle root of the merkle tree -#define macro MERKLE_DISTRIBUTOR_CONSTRUCTOR() = takes (0) returns (0) { - // Copy the first argument into memory - 0x20 // [size] - byte size to copy - 0x40 codesize sub // [offset, size] - offset in the code to copy from - 0x00 // [mem, offset, size] - offset in memory to copy to - codecopy // [] - - // Store the first argument in storage - 0x00 mload // [arg1] - [TOKEN_ADDR_SLOT] // [TOKEN_ADDR, arg1] - sstore // [] - - // Copy the second argument into memory - 0x20 // [size] - byte size to copy - 0x20 codesize sub // [offset, size] - offset in the code to copy from - 0x00 // [mem, offset, size] - offset in memory to copy to - codecopy // [] - - // Store the second argument in storage - 0x00 mload // [arg2] - [MERKLE_ROOT_SLOT] // [CONSTRUCTOR_ARG_TWO, arg2] - sstore // [] -} - -/// @notice Function Dispatch -/// @notice Takes the first 4 bytes of calldata (aka the function selector) and dispatches to the appropriate function -/// @notice If non match, execution proceeds as the code is inlined -#define macro MERKLE_DISTRIBUTOR_MAIN() = takes (1) returns (1) { - // Input Stack: [function_selector] - - dup1 __FUNC_SIG(getTokenAddress) eq getTokenAddress jumpi - dup1 __FUNC_SIG(getMerkleRoot) eq getMerkleRoot jumpi - dup1 __FUNC_SIG(isClaimed) eq isClaimed jumpi - dup1 __FUNC_SIG(claim) eq claim jumpi - - // Jump to the end if non match - no_match jump - - getMerkleRoot: - GET_MERKLE_ROOT() - getTokenAddress: - GET_TOKEN_ADDR() - isClaimed: - IS_CLAIMED() - claim: - CLAIM() - - no_match: -} \ No newline at end of file diff --git a/src/utils/__TEMP__syuldunwuhcelrjhrahufjtvdthjstmmMulticallable.huff b/src/utils/__TEMP__syuldunwuhcelrjhrahufjtvdthjstmmMulticallable.huff deleted file mode 100644 index 58569a85..00000000 --- a/src/utils/__TEMP__syuldunwuhcelrjhrahufjtvdthjstmmMulticallable.huff +++ /dev/null @@ -1,233 +0,0 @@ -#define function multicall(bytes[] calldata) payable returns (bytes[] memory) -#define function call1() view returns (uint256) -#define function call2() view returns (uint256) -#define function call3() view returns (uint256) -#define function returnsTuple(uint256, uint256) view returns (uint256, uint256) -#define function returnsStr(string) view returns (string) -#define function returnsSender() view returns (address) -#define function pay() payable returns (uint256) -#define function paid() view returns (uint256) -#define function revertsNoMsg() view returns () -#define function revertsMsg() view returns () - -#define constant PAID_SLOT = FREE_STORAGE_POINTER() - -#define macro CALL_1() = takes (0) returns (0) { - 0x11 0x00 mstore - 0x20 0x00 return -} - -#define macro CALL_2() = takes (0) returns (0) { - 0x22 0x00 mstore - 0x20 0x00 return -} - -#define macro CALL_3() = takes (0) returns (0) { - 0x33 0x00 mstore - 0x20 0x00 return -} - -#define macro RETURNS_TUPLE() = takes (0) returns (0) { - 0x04 calldataload // [x] - 0x00 mstore // [] - 0x24 calldataload // [y] - 0x20 mstore // [] - 0x40 0x00 return -} - -#define macro RETURNS_STR() = takes (0) returns (0) { - 0x24 calldataload // [str_len] - 0x40 add // [str_len + 0x40] - dup1 // [str_len + 0x40, str_len + 0x40] - 0x04 // [0x04, str_len + 0x40, str_len + 0x40] - 0x00 // [0x00, 0x04, str_len + 0x40, str_len + 0x40] - calldatacopy // [str_len + 0x40] - 0x00 return -} - -#define macro RETURNS_SENDER() = takes (0) returns (0) { - caller // [msg.sender] - 0x00 mstore // [] - 0x20 0x00 return -} - -#define macro PAY() = takes (0) returns (0) { - [PAID_SLOT] sload // [paid] - callvalue add // [paid + callvalue] - [PAID_SLOT] sstore // [] - 0x00 dup1 return -} - -#define macro PAID() = takes (0) returns (0) { - [PAID_SLOT] sload // [paid] - 0x00 mstore // [] - 0x20 0x00 return -} - -#define macro REVERTS_NO_MSG() = takes (0) returns (0) { - 0x00 dup1 revert -} - -#define macro REVERTS_MSG() = takes (0) returns (0) { - 0x5465737420526576657274000000000000000000000000000000000000000000 - 0x00 mstore - 0x0B 0x00 revert -} - -#define macro MAIN() = takes (0) returns (0) { - pc calldataload 0xE0 shr - dup1 __FUNC_SIG(multicall) eq multicall jumpi - dup1 __FUNC_SIG(call1) eq call_one jumpi - dup1 __FUNC_SIG(call2) eq call_two jumpi - dup1 __FUNC_SIG(call3) eq call_three jumpi - dup1 __FUNC_SIG(returnsTuple) eq returns_tuple jumpi - dup1 __FUNC_SIG(returnsStr) eq returns_str jumpi - dup1 __FUNC_SIG(returnsSender) eq returns_sender jumpi - dup1 __FUNC_SIG(pay) eq pay jumpi - dup1 __FUNC_SIG(paid) eq paid jumpi - dup1 __FUNC_SIG(revertsNoMsg) eq revert_no_msg jumpi - dup1 __FUNC_SIG(revertsMsg) eq revert_msg jumpi - - 0x00 dup1 revert - - multicall: - MULTICALL() - call_one: - CALL_1() - call_two: - CALL_2() - call_three: - CALL_3() - returns_tuple: - RETURNS_TUPLE() - returns_str: - RETURNS_STR() - returns_sender: - RETURNS_SENDER() - pay: - PAY() - paid: - PAID() - revert_no_msg: - REVERTS_NO_MSG() - revert_msg: - REVERTS_MSG() -} - -/// @title Multicallable -/// @notice SPDX-License-Identifier: MIT -/// @author clabby -/// @notice Enables a single call to call multiple methods within a contract. -/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/Multicallable.sol) -/// @author Adapted from Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/Multicallable.sol) - -// Calldata -#define constant DATA_LEN = 0x24 -#define constant DATA_OFFSET = 0x44 -// Memory -#define constant RES = 0x20 -#define constant RES_OFF = 0x40 - -/// @notice Multicall function entry point. -/// @dev This macro should be placed alone under a function selector's jump label. -/// -/// Expected calldata: `bytes[]` containing valid ABI-encoded function calls -/// as elements. -/// -/// Note: this macro only allows for multicalling functions that are within -/// the contract it is invoked in. -#define macro MULTICALL() = takes (0) returns (0) { - // Input stack: [] - - // Store pointer to array contents @ 0x00 - 0x20 0x00 mstore // [] - - [DATA_LEN] // [data_len_ptr] - calldataload // [data_len] - - // Only continue if data length is > 0 - dup1 continue jumpi - - // Return blank bytes array - 0x40 0x00 return - - continue: - - dup1 // [data_len, data_len] - [RES] // [res_ptr, data_len, data_len] - mstore // [data_len] - - [RES_OFF] // [results_offset, data_len] - - // Copy the offsets from calldata into memory. - swap1 // [data_len, results_offset] - 0x05 shl // [data_len * 0x20, results_offset] - dup1 // [data_len * 0x20, data_len * 0x20, results_offset] - [DATA_OFFSET] // [data_offset, data_len * 0x20, data_len * 0x20, results_offset] - dup4 // [results_offset, data_offset, data_len * 0x20, data_len * 0x20, results_offset] - calldatacopy // [data_len * 0x20, results_offset] - - dup2 add // [mem_ptr, results_offset] - dup1 // [data_end, mem_ptr, results_offset] - loop: - // The offset of the current bytes in the calldata. - dup3 // [results_offset, data_end, mem_ptr, results_offset] - mload // [result, data_end, mem_ptr, results_offset] - [DATA_OFFSET] // [0x44, result, data_end, mem_ptr, results_offset] - add // [o, data_end, mem_ptr, results_offset] - - // Copy the current bytes from calldata to the memory. - dup1 // [o, o, data_end, mem_ptr, results_offset] - calldataload // [cur_bytes_len, o, data_end, mem_ptr, results_offset] - dup2 0x20 add // [o + 0x20, cur_bytes_len, o, data_end, mem_ptr, results_offset] - dup5 // [mem_ptr, o + 0x20, cur_bytes_len, o, data_end, mem_ptr, results_offset] - calldatacopy // [o, data_end, mem_ptr, results_offset] - - calldataload // [cur_bytes_len, data_end, mem_ptr, results_offset] - 0x00 dup1 // [0x00, 0x00, cur_bytes_len, data_end, mem_ptr, results_offset] - swap2 // [cur_bytes_len, 0x00, 0x00, data_end, mem_ptr, results_offset] - dup5 // [mem_ptr, cur_bytes_len, 0x00, 0x00, data_end, mem_ptr, results_offset] - address // [self_addr, mem_ptr, cur_bytes_len, 0x00, 0x00, data_end, mem_ptr, results_offset] - gas // [gas, self_addr, mem_ptr, cur_bytes_len, 0x00, 0x00, data_end, mem_ptr, results_offset] - delegatecall // [call_result, data_end, mem_ptr, results_offset] - - // Bubble up the revert if the delegatecall reverts - iszero fail jumpi // [data_end, mem_ptr, results_offset] - - // Increment `results_offset` by 0x20 - 0x40 dup3 sub // [mem_ptr - 0x40, data_end, mem_ptr, results_offset] - dup4 mstore // [data_end, mem_ptr, results_offset] - dup3 0x20 add // [results_offset + 0x20, data_end, mem_ptr, results_offset] - swap3 pop // [data_end, mem_ptr, results_offset] - - // Append the `returndatasize()`, and the return data. - returndatasize // [ret_data_size, data_end, mem_ptr, results_offset] - dup3 // [mem_ptr, ret_data_size, data_end, mem_ptr, results_offset] - mstore // [data_end, mem_ptr, results_offset] - returndatasize // [ret_data_size, data_end, mem_ptr, results_offset] - 0x00 // [0x00, ret_data_size, data_end, mem_ptr, results_offset] - dup4 0x20 add // [mem_ptr + 0x20, 0x00, ret_data_size, data_end, mem_ptr, results_offset] - returndatacopy // [data_end, mem_ptr, results_offset] - - // Advance the `memPtr` by `returndatasize() + 0x20`, - // rounded up to the next multiple of 32. - 0xffffffffffffffe0 - 0x3f // [0x3f, 0xf..e0, data_end, mem_ptr, results_offset] - returndatasize // [ret_data_size, 0x3f, 0xf..e0, data_end, mem_ptr, results_offset] - dup5 add // [mem_ptr + ret_data_size, 0x3f, 0xf..e0, data_end, mem_ptr, results_offset] - add and // [(mem_ptr + ret_data_size + 0x3f) & 0xf..e0, data_end, mem_ptr, results_offset] - swap2 pop // [data_end, mem_ptr, results_offset] - - // Continue loop if results_offset < data_end - dup1 dup4 lt // [results_offset < data_end, data_end, mem_ptr, results_offset] - loop jumpi // [data_end, mem_ptr, results_offset] - - swap1 // [mem_ptr, data_end, results_offset] - 0x00 // [ret_mem_ptr, mem_ptr, data_end, results_offset] - return - fail: - returndatasize // [ret_data_size, data_end, mem_ptr, results_offset] - 0x00 dup1 // [0x00, 0x00, ret_data_size, data_end, mem_ptr, results_offset] - returndatacopy // [ret_data_size, data_end, mem_ptr, results_offset] - returndatasize 0x00 revert -} \ No newline at end of file diff --git a/src/utils/__TEMP__tvibuicjahwdnvquznelrjppmvqtmvduSafeTransferLib.huff b/src/utils/__TEMP__tvibuicjahwdnvquznelrjppmvqtmvduSafeTransferLib.huff deleted file mode 100644 index e62c27e4..00000000 --- a/src/utils/__TEMP__tvibuicjahwdnvquznelrjppmvqtmvduSafeTransferLib.huff +++ /dev/null @@ -1,202 +0,0 @@ -#define function safeTransferETH(address, uint256) payable returns () -#define function safeTransferFrom(address, address, address, uint256) nonpayable returns () -#define function safeTransfer(address, address, uint256) nonpayable returns () -#define function safeApprove(address, address, uint256) nonpayable returns () - -#define macro SAFE_TRANSFER_ETH_WRAPPER() = { - 0x24 calldataload // [amount] - 0x04 calldataload // [to, amount] - - SAFE_TRANSFER_ETH() - stop -} - -#define macro SAFE_TRANSFER_FROM_WRAPPER() = { - 0x04 calldataload // [token] - 0x64 calldataload // [amount, token] - 0x44 calldataload // [to, amount, token] - 0x24 calldataload // [from, to, amount, token] - - SAFE_TRANSFER_FROM(0x00) - stop -} - -#define macro SAFE_TRANSFER_WRAPPER() = { - 0x04 calldataload // [token] - 0x44 calldataload // [amount, token] - 0x24 calldataload // [to, amount, token] - - SAFE_TRANSFER(0x00) - stop -} - -#define macro SAFE_APPROVE_WRAPPER() = { - 0x04 calldataload // [token] - 0x44 calldataload // [amount, token] - 0x24 calldataload // [to, amount, token] - - SAFE_APPROVE(0x00) - stop -} - -#define macro MAIN() = { - pc calldataload 0xE0 shr - dup1 __FUNC_SIG(safeTransferETH) eq steth jumpi - dup1 __FUNC_SIG(safeTransferFrom) eq stf jumpi - dup1 __FUNC_SIG(safeTransfer) eq st jumpi - dup1 __FUNC_SIG(safeApprove) eq sa jumpi - - 0x00 dup1 revert - - steth: - SAFE_TRANSFER_ETH_WRAPPER() - stf: - SAFE_TRANSFER_FROM_WRAPPER() - st: - SAFE_TRANSFER_WRAPPER() - sa: - SAFE_APPROVE_WRAPPER() -} - - -/// @title SafeTransferLib -/// @notice SPDX-License-Identifier: MIT -/// @notice Safe ETH and ERC20 transfer library that gracefully handles missing return values. -/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/SafeTransferLib.sol) -/// @author Modified from Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/SafeTransferLib.sol) -/// @author clabby -/// @dev Caution! This library won't check that a token has code, responsibility is delegated to the caller. - -/// CONSIDERATION: -/// We could designate byte scratch space for memory -/// which would spare us runtime operations shifting the dynamic memory pointer -/// -/// Designations: -/// - 128 bytes for SAFE_TRANSFER_FROM -/// - 96 bytes for SAFE_TRANSFER -/// - 96 bytes for SAFE_APPROVE - - -/// @notice Safely transfers an `amount` of eth to the address `to` -#define macro SAFE_TRANSFER_ETH() = takes (2) { - // Input stack: [to, amount] - // Output stack: [] - - 0x00 dup1 dup1 dup1 // [0x00, 0x00, 0x00, 0x00, to, amount] - swap5 swap1 swap4 // [to, amount, 0x00, 0x00, 0x00, 0x00] - gas call // [call_success] - success jumpi // [] - - // `ETHTransferFailed()` error - 0xb12d13eb 0x00 mstore - 0x04 0x1c revert - - success: -} - -/// @notice Safely transfers an `amount` of `token` from an address `from` to the address `to` -#define macro SAFE_TRANSFER_FROM(mem_ptr) = takes (4) { - // Input stack: [from, to, value, token] - // Output stack: [] - - __RIGHTPAD(0x23b872dd) // [transferFrom_selector, from, to, amount, token] - // [mem_ptr, transferFrom_selector, from, to, amount, token] - mstore // [from, to, amount, token] - - 0x04 add // [mem_ptr + 0x04, from, to, amount, token] - mstore // [to, amount, token] - 0x24 add // [mem_ptr + 0x24, to, amount, token] - mstore // [amount, token] - 0x44 add // [mem_ptr + 0x44, amount, token] - mstore // [token] - - 0x64 // [0x64, mem_ptr, token] - dup2 0x00 // [0x00, mem_ptr, 0x64, mem_ptr, token] - 0x20 swap5 // [token, 0x00, mem_ptr, 0x64, mem_ptr, 0x20] - gas call // [success] - - returndatasize // [returndatasize, success] - iszero // [returndatasize == 0, success] - // [offset, returndatasize == 0, success] - mload // [data, returndatasize == 0, success] - 0x01 eq // [data == 0x01, returndatasize == 0, success] - or // [data == 0x01 | returndatasize == 0, success] - - and // [success & (data == 0x01 | returndatasize == 0)] - success jumpi // [] - - 0x7939f424 0x00 mstore - 0x04 0x1c revert - - success: -} - -/// @notice Safely transfers an `amount` to an address `to` for the provided `token` -#define macro SAFE_TRANSFER(mem_ptr) = takes (3) { - // Input stack: [to, amount, token] - // Output stack: [] - - __RIGHTPAD(0xa9059cbb) // [transfer_selector, to, amount, token] - // [mem_ptr, transfer_selector, to, amount, token] - mstore // [to, amount, token] - - 0x04 add // [mem_ptr + 0x04, to, amount, token] - mstore // [amount, token] - 0x24 add // [mem_ptr + 0x24, amount, token] - mstore - - 0x44 // [0x44, mem_ptr, token] - dup2 0x00 // [0x00, mem_ptr, 0x44, mem_ptr, token] - 0x20 swap5 // [token, 0x00, mem_ptr, 0x44, mem_ptr, 0x20] - gas call // [success] - - returndatasize // [returndatasize, success] - iszero // [returndatasize == 0, success] - // [offset, returndatasize == 0, success] - mload // [data, returndatasize == 0, success] - 0x01 eq // [data == 0x01, returndatasize == 0, success] - or // [data == 0x01 | returndatasize == 0, success] - - and // [success & (data == 0x01 | returndatasize == 0)] - success jumpi // [] - - 0x90b8ec18 0x00 mstore - 0x04 0x1c revert - - success: -} - -/// @notice Safely approves an `amount` for an address `to` for the provided `token` -#define macro SAFE_APPROVE(mem_ptr) = takes (3) { - // Input stack: [spender, value, token] - // Output stack: [] - - __RIGHTPAD(0x095ea7b3) // [approve_selector, to, amount, token] - // [mem_ptr, approve_selector, to, amount, token] - mstore // [to, amount, token] - - 0x04 add // [mem_ptr + 0x04, to, amount, token] - mstore // [amount, token] - 0x24 add // [mem_ptr + 0x24, amount, token] - mstore - - 0x44 // [0x44, mem_ptr, token] - dup2 0x00 // [0x00, mem_ptr, 0x44, mem_ptr, token] - 0x20 swap5 // [token, 0x00, mem_ptr, 0x44, mem_ptr, 0x20] - gas call // [success] - - returndatasize // [returndatasize, success] - iszero // [returndatasize == 0, success] - // [offset, returndatasize == 0, success] - mload // [data, returndatasize == 0, success] - 0x01 eq // [data == 0x01, returndatasize == 0, success] - or // [data == 0x01 | returndatasize == 0, success] - - and // [success & (data == 0x01 | returndatasize == 0)] - success jumpi // [] - - 0x3e3f8f73 0x00 mstore - 0x04 0x1c revert - - success: -} diff --git a/src/utils/__TEMP__ubhvkcstcqznkwuhmkwwvrdjviacaricEthers.huff b/src/utils/__TEMP__ubhvkcstcqznkwuhmkwwvrdjviacaricEthers.huff deleted file mode 100644 index 12fda5c0..00000000 --- a/src/utils/__TEMP__ubhvkcstcqznkwuhmkwwvrdjviacaricEthers.huff +++ /dev/null @@ -1,47 +0,0 @@ - -// Receives ether -#define function isPayable() payable returns (uint256) -#define function nonPayable() nonpayable returns (uint256) - -// Match the function selector -#define macro MAIN() = takes (0) returns (0) { - pc calldataload 0xe0 shr - - dup1 __FUNC_SIG(isPayable) eq payable_jump jumpi - dup1 __FUNC_SIG(nonPayable) eq non_payable_jump jumpi - - // Revert if no function selectors match - reverts: - 0x00 dup1 revert - - non_payable_jump: - callvalue iszero iszero reverts jumpi - payable_jump: - balance 0x00 mstore - 0x20 0x00 return -} - -/// @title Ethers -/// @notice SPDX-License-Identifier: MIT -/// @author asnared -/// @notice Utilities for working with ether at a low level - -/// @notice Sends an amount of ether to the specified [amount, address] -#define macro SEND_ETH() = takes (2) returns (1) { - // Input Stack: [amount, address] - - // Send the ether - 0x00 // [0, amount, address] - dup1 // [0, 0, amount, address] - dup1 // [0, 0, 0, amount, address] - dup1 // [0, 0, 0, 0, amount, address] - dup5 // [amount, 0, 0, 0, 0, amount, address] - dup7 // [address, amount, 0, 0, 0, 0, amount] - gas // [gas, address, amount, 0, 0, 0, 0, amount, address] - call // [success, amount, address] - - // Clean the stack - swap2 // [address, amount, success] - pop // [success, address] - pop // [success] -} \ No newline at end of file diff --git a/src/utils/__TEMP__vamkrwmxfmambbznmfrsntcscmmocveeDateTimeLib.huff b/src/utils/__TEMP__vamkrwmxfmambbznmfrsntcscmmocveeDateTimeLib.huff deleted file mode 100644 index 04bae5ed..00000000 --- a/src/utils/__TEMP__vamkrwmxfmambbznmfrsntcscmmocveeDateTimeLib.huff +++ /dev/null @@ -1,517 +0,0 @@ -/* Functions */ -#define function weekday(uint256) nonpayable returns (uint256) -#define function isLeapYear(uint256) nonpayable returns (bool) -#define function daysInMonth(uint256,uint256) nonpayable returns (uint256) -#define function dateToEpochDay(uint256,uint256,uint256) nonpayable returns (uint256) -#define function dateToTimestamp(uint256,uint256,uint256) nonpayable returns (uint256) -#define function dateTimeToTimestamp(uint256,uint256,uint256,uint256,uint256,uint256) nonpayable returns (uint256) -#define function nthWeekdayInMonthOfYearTimestamp(uint256, uint256,uint256,uint256) nonpayable returns (uint256) -#define function epochDayToDate(uint256) nonpayable returns (uint256,uint256,uint256) -#define function timestampToDate(uint256) nonpayable returns (uint256,uint256,uint256) - -/* Wrapper Macros */ -#define macro WEEKDAY_WRAPPER() = takes (0) returns (0) { - 0x04 calldataload // [timestamp] - WEEKDAY() // [result] - 0x00 mstore // [] - 0x20 0x00 return // [] - } - -#define macro IS_LEAP_YEAR_WRAPPER() = takes (0) returns (0) { - 0x04 calldataload // [timestamp] - IS_LEAP_YEAR() // [result] - 0x00 mstore // [] - 0x20 0x00 return // [] - } - -#define macro DAYS_IN_MONTH_WRAPPER() = takes (0) returns (0) { - 0x04 calldataload // [year] - 0x24 calldataload // [month, year] - DAYS_IN_MONTH() // [result] - 0x00 mstore // [] - 0x20 0x00 return // [] - } - -#define macro DATE_TO_EPOCH_DAY_WRAPPER() = takes (0) returns (0) { - 0x04 calldataload // [year] - 0x24 calldataload // [month, year] - 0x44 calldataload // [day, month, year] - DATE_TO_EPOCH_DAY() // [result] - 0x00 mstore // [] - 0x20 0x00 return // [] - } - - #define macro DATE_TO_TIMESTAMP_WRAPPER() = takes (0) returns (0) { - 0x04 calldataload // [year] - 0x24 calldataload // [month, year] - 0x44 calldataload // [day, month, year] - DATE_TO_TIMESTAMP() // [result] - 0x00 mstore // [] - 0x20 0x00 return // [] - } - - #define macro DATE_TIME_TO_TIMESTAMP_WRAPPER() = takes (0) returns (0) { - 0x04 calldataload // [year] - 0x24 calldataload // [month, year] - 0x44 calldataload // [day, month, year] - 0x64 calldataload // [seconds, day, month, year] - 0x84 calldataload // [minutes, seconds, day, month, year] - 0xa4 calldataload // [hours, minutes, seconds, day, month, year] - DATE_TIME_TO_TIMESTAMP() // [result] - 0x00 mstore // [] - 0x20 0x00 return // [] - } - - #define macro EPOCH_DAY_TO_DATE_WRAPPER() = takes (0) returns (0) { - 0x04 calldataload // [epochDay] - EPOCH_DAY_TO_DATE() // [year, month, day] - 0x00 mstore // [month, day] - 0x20 mstore // [day] - 0x40 mstore // [] - 0x60 0x00 return // [] - } - - #define macro TIMESTAMP_TO_DATE_WRAPPER() = takes (0) returns (0) { - 0x04 calldataload // [timestamp] - TIMESTAMP_TO_DATE() // [year, month, day] - 0x00 mstore // [month, day] - 0x20 mstore // [day] - 0x40 mstore // [] - 0x60 0x00 return // [] - } - - - - #define macro NTH_WEEKDAY_IN_MONTH_OF_YEAR_TIMESTAMP_WRAPPER() = takes (0) returns (0) { - 0x04 calldataload // [year] - 0x24 calldataload // [month, year] - 0x44 calldataload // [n, month, year] - 0x64 calldataload // [wd, n, month, year] - NTH_WEEKDAY_IN_MONTH_OF_YEAR_TIMESTAMP() // [result] - 0x00 mstore // [] - 0x20 0x00 return // [] - } - -/* Function Dispatcher */ -#define macro MAIN() = takes (0) returns (0) { - // Identify which function is being called. - 0x00 calldataload - - // Extract the function singature - 0xe0 shr - - // Jump table - dup1 __FUNC_SIG(weekday) eq weekday jumpi - dup1 __FUNC_SIG(isLeapYear) eq isLeapYear jumpi - dup1 __FUNC_SIG(daysInMonth) eq daysInMonth jumpi - dup1 __FUNC_SIG(dateToEpochDay) eq dateToEpochDay jumpi - dup1 __FUNC_SIG(epochDayToDate) eq epochDayToDate jumpi - dup1 __FUNC_SIG(timestampToDate) eq timestampToDate jumpi - dup1 __FUNC_SIG(dateToTimestamp) eq dateToTimestamp jumpi - dup1 __FUNC_SIG(dateTimeToTimestamp) eq dateTimeToTimestamp jumpi - dup1 __FUNC_SIG(nthWeekdayInMonthOfYearTimestamp) eq nthWeekdayInMonthOfYearTimestamp jumpi - - - weekday: - WEEKDAY_WRAPPER() - - isLeapYear: - IS_LEAP_YEAR_WRAPPER() - - daysInMonth: - DAYS_IN_MONTH_WRAPPER() - - dateToEpochDay: - DATE_TO_EPOCH_DAY_WRAPPER() - - epochDayToDate: - EPOCH_DAY_TO_DATE_WRAPPER() - - timestampToDate: - TIMESTAMP_TO_DATE_WRAPPER() - - dateToTimestamp: - DATE_TO_TIMESTAMP_WRAPPER() - - dateTimeToTimestamp: - DATE_TIME_TO_TIMESTAMP_WRAPPER() - - nthWeekdayInMonthOfYearTimestamp: - NTH_WEEKDAY_IN_MONTH_OF_YEAR_TIMESTAMP_WRAPPER() - -} - - - - -/// @title DateTimeLib -/// @notice SPDX-License-Identifier: MIT -/// @author PraneshASP -/// @notice Library for date time operations. -/// @notice Adapted from Solady (https://github.com/Vectorized/solady/blob/main/src/utils/DateTimeLib.so) - -/// Conventions: -/// --------------------------------------------------------------------+ -/// Unit | Range | Notes | -/// --------------------------------------------------------------------| -/// timestamp | 0..0x1e18549868c76ff | Unix timestamp. | -/// epochDay | 0..0x16d3e098039 | Days since 1970-01-01. | -/// year | 1970..0xffffffff | Gregorian calendar year. | -/// month | 1..12 | Gregorian calendar month. | -/// day | 1..31 | Gregorian calendar day of month. | -/// weekday | 1..7 | The day of the week (1-indexed). | -/// --------------------------------------------------------------------+ -/// All timestamps of days are rounded down to 00:00:00 UTC. - -//////////////////////////////////////////////////////////////// -// Logic // -//////////////////////////////////////////////////////////////// - -/// @dev Returns day of the week (Monday is indicated as 1 and so on) -#define macro WEEKDAY() = takes (0) returns (0) { - // Formula: ((timestamp / 86400 + 3) % 7) + 1; - - // Input Stack: [timestamp(t)] - - 0x15180 // [86400, t] - swap1 // [t,86400] - div // [t/86400] - 0x03 // [3, t/86400] - add // [3 + t/86400] - 0x07 // [7, (3+t/86400)] - swap1 // [(t/86400 + 3), 7] - mod // [(t/86400 + 3) % 7] - 0x01 // [1, (t/86400 + 3)%7] - add // [1 + (t/86400 + 3)%7] - - // Return stack: [result] -} - -#define macro IS_LEAP_YEAR() = takes (0) returns (0) { - // Condition 1, C1 = year % 4 == 0 - // Condition 2, C2 = year % 100 != 0 - // Condition 3, C3 = year % 400 == 0 - - // Formula: C1 && (C2||C3) - - // Input stack: [year] - - // Calculate C2 - 0x64 // [100, year] - dup2 // [year, 100, year] - mod // [year % 100, year] - iszero // [year % 100 == 0, year] - not // [C2, year] - - // Calculate C1 - 0x04 // [4, C2, year] - dup3 // [year, 4, C2, year] - mod // [year % 4, C2, year] - iszero // [C1, C2, year] - - // Calculate C3 - swap2 // [year, C2, C1] - 0x190 // [400, year, C2, C1] - swap1 // [year, 400, C2, C1] - mod // [year % 400, C2, C1] - iszero // [C3, C2, C1] - or // [(C2||C3), C1] - and // [(C2||C3) && C1] - - // Return stack: [result] -} - - -#define macro DAYS_IN_MONTH() = takes (0) returns (0) { - // Input Stack : [month, year] - - // Push days in month map: [31,28,31,30,31,30,31,31,30,31,30,31] - 0x1F1C1F1E1F1E1F1F1E1F1E1F // [daysInMonthMap, month, year] - - dup2 // [month, daysInMonthMap, month, year] - 0x13 // [19, month, daysInMonthMap, month, year] - add // [monthOffset, daysInMonthMap, month, year] - byte // [daysInMonth, month, year] - swap2 // [year, month, daysInMonth] - IS_LEAP_YEAR() // [isleap(year), month, daysInMonth] - swap1 // [month, isleap(year), daysInMonth] - 0x02 // [2, month, isleap(year), daysInMonth] - eq // [2 == month, isleap(year), daysInMonth] - and // [2==month && isleap(year), daysInMonth] - add // [2==month && isleap(year) + daysInMonth] - - // Return stack: [result] -} - - -#define macro DATE_TO_EPOCH_DAY() = takes (0) returns (0) { - // Input stack : [d, m, y] - swap2 // [y,m,d] - 0x3 // [3,y,m,d] - dup3 // [m,3,y,m,d] - lt // [m < 3, y,m,d] - swap1 // [y, m<3, m,d] - sub // [y-m<3,m,d] - // y = y - (m<3) - /// doy construction - dup3 // [d, y,m,d] - 0x301 // [769,d, y, m, d] - 0xc // [12, 769,d, y, m, d] - 0x9 // [9,12, 769,d, y, m, d] - dup6 // [m, 9,12, 769,d, y, m, d] - add // [m + 9,12, 769, d, y, m, d] - mod // [m + 9 % 12, 769, d, y, m, d] - 0xf4ff // [62719, m + 9 % 12, 769,d, y, m, d] - mul // [62719 * m + 9 % 12, 769, d, y, m, d] - add // [62719 * m + 9 % 12 + 769,d, y, m, d] - 0xb // [11, 62719 * m + 9 % 12 + 769, d, y, m, d] - shr // [62719 * m + 9 % 12 + 769 >> 11, d, y, m, d] - add // [62719 * m + 9 % 12 + 769 >> 11 + d, y, m, d] - // [doy, y,m,d] - - /// yoe construction - 0x190 // [400,doy,y,m,d] - dup3 // [y,400, doy,y,m,d] - mod // [y%400, doy, y, m,d] - // [yoe, doy, y, m, d] - /// doe construction - 0x64 // [100, yoe, doy, y, m, d] - dup2 // [yoe, 100, yoe, doy, y, m, d] - div // [yoe / 100, yoe, doy, y, m, d] - dup3 // [doy, yoe / 100, yoe, doy, y, m, d] - dup3 // [yoe, doy, yoe / 100, yoe, doy, y, m, d] - 0x2 // [2, yoe, doy, yoe / 100, yoe, doy, y, m, d] - shr // [yoe >> 2, doy, yoe / 100, yoe, doy, y, m, d] - 0x16d // [365, yoe >> 2, doy, yoe / 100, yoe, doy, y, m, d] - dup5 // [yoe, 365, yoe >> 2, doy, yoe / 100, yoe, doy, y, m, d] - mul // [yoe * 365, yoe >> 2, doy, yoe / 100, yoe, doy, y, m, d] - add // [yoe * 365 + yoe >> 2, doy, yoe / 100, yoe, doy, y, m, d] - add // [yoe * 365 + yoe >> 2 + doy, yoe / 100, yoe, doy, y, m, d] - sub // [yoe * 365 + yoe >> 2 + doy - yoe / 100, yoe, doy, y, m, d] - // [doe, yoe, doy, y, m, d] - - 0xafa6d // [719469, doe, yoe, doy, y, m, d] - swap1 // [doe, 719469, yoe, doy, y, m, d] - 0x23ab1 // [146097, doe, 719469, yoe, doy, y, m, d] - 0x190 // [400, 146097, doe, 719469, yoe, doy, y, m, d] - dup7 // [y, 400, 146097, doe, 719469, yoe, doy, y, m, d] - div // [y / 400, 146097, doe, 719469, yoe, doy, y, m, d] - mul // [y / 400 * 146097, doe, 719469, yoe, doy, y, m, d] - add // [y / 400 * 146097 + doe, 719469, yoe, doy, y, m, d] - sub // [y / 400 * 146097 + doe - 719469, yoe, doy, y, m, d] - - // Clear stack - swap5 - pop pop pop pop pop - - // Return stack: // [result] -} - -#define macro DATE_TO_TIMESTAMP() = takes (0) returns (0) { - // Input stack = [d, m, y] - DATE_TO_EPOCH_DAY() // [epochDay] - 0x15180 // [86400, epochDay] - mul // [86400 * epochDay] - // Return stack: // [timestamp] -} - - -#define macro NTH_WEEKDAY_IN_MONTH_OF_YEAR_TIMESTAMP() = takes (0) returns (0) { - // Input stack: [wd, n, m, y] - dup4 // [y, wd, n, m, y] - dup4 // [m, y, wd, n, m, y] - 0x1 // [1, m, y, wd, n, m, y] - DATE_TO_EPOCH_DAY() // [d, wd, n, m, y] - - dup5 // [y, d, wd, n, m, y] - dup5 // [m, y, d, wd, n, m, y] - DAYS_IN_MONTH() // [md, d, wd, n, m, y] - - 0x1 // [1, md, d, wd, n, m, y] - 0x7 // [7, 1, md, d, wd, n, m, y] - 0x3 // [3, 7, 1, md, d, wd, n, m, y] - dup5 // [d, 3, 7, 1, md, d, wd, n, m, y] - add // [d + 3, 7, 1, md, d, wd, n, m, y] - mod // [d + 3 % 7, 1, md, d, wd, n, m, y] - add // [d + 3 % 7 + 1, md, d, wd, n, m, y] - dup4 // [wd, d + 3 % 7 + 1, md, d, wd, n, m, y] - sub // [wd - d + 3 % 7 + 1, md, d, wd, n, m, y] - // [diff, md, d, wd, n, m, y] - - 0x7 // [7, diff, md, d, wd, n, m, y] - 0x6 // [6, 7, diff, md, d, wd, n, m, y] - dup3 // [diff, 6, 7, diff, md, d, wd, n, m, y] - gt // [diff > 6, 7, diff, md, d, wd, n, m, y] - mul // [diff > 6 * 7, diff, md, d, wd, n, m, y] - add // [diff > 6 * 7 + diff, md, d, wd, n, m, y] - 0x7 // [7,diff > 6 * 7 + diff, md, d, wd, n, m, y] - 0x1 // [1, 7, diff > 6 * 7 + diff, md, d, wd, n, m, y] - dup7 // [n, 1, 7,diff > 6 * 7 + diff, md, d, wd, n, m, y] - sub // [n - 1, 7,diff > 6 * 7 + diff, md, d, wd, n, m, y] - mul // [n - 1 * 7,diff > 6 * 7 + diff, md, d, wd, n, m, y] - add // [n - 1 * 7 + diff > 6 * 7 + diff, md, d, wd, n, m, y] - // [date, md, d, wd, n, m, y] - - swap4 // [n, md, d, wd, date, m, y] - iszero // [n==0, md, d,wd, date, m, y] - iszero // [((n==0)==0), md, d, wd, date, m, y] - swap1 // [md,((n==0)==0),d,wd, date,m,y] - dup5 // [date, md,((n==0)==0),d,wd, date,m,y] - lt // [date < md,((n==0)==0),d,wd,date,m,y] - and // [date < md && ((n==0)==0),d,wd,date,m,y] - swap1 // [d, date < md && ((n==0)==0),wd, date,m,y] - dup4 // [date, d, date < md && ((n==0)==0),wd, date,m,y] - add // [date + d, date < md && ((n==0)==0),wd,date,m,y] - 0x15180 // [86400, date + d, date < md && ((n==0)==0),wd,date,m,y] - mul // [86400 * date + d, date < md && ((n==0)==0),wd, date,m,y] - mul // [86400 * date + d * date < md && ((n==0)==0),wd,date,m,y] - - // clear stack - swap4 - pop pop - pop pop - - // Return stack: // [result] -} - - - -#define macro DATE_TIME_TO_TIMESTAMP() = takes(0) returns(0) { - // Input stack : [day, month ,year ,hour,min,sec] - - DATE_TO_EPOCH_DAY() // [epochDay, hour, min, sec] - 0x15180 // [86400,epochDay, hour, min, sec] - mul // [86400*epochDay, hour, min, sec] - swap1 // [hour, 86400*epochDay, min, sec] - 0xe10 // [3600,hour, 86400*epochDay, min, sec] - mul // [3600*hour, 86400*epochDay, min, sec] - swap2 // [min, 86400*epochDay, 3600*hour, sec] - 0x3c // [60,min, 86400*epochDay, 3600*hour, sec] - mul // [60 * min, 86400*epochDay, 3600*hour, sec] - add // [60 * min + 86400*epochDay, 3600*hour, sec] - add // [60 * min + 86400*epochDay + 3600*hour, sec] - add // [60 * min + 86400*epochDay + 3600*hour + sec] - - // Return stack: [result] -} - -#define macro GET_DAY() = takes(0) returns(0) { - // Input stack: [mp, doy, yoe, doe, epochDay] - - 0x1 // [1, mp, doy, yoe, doe, epochDay] - 0x301 // [769, 1, mp, doy, yoe, doe, epochDay] - 0xf4ff // [62719, 769, 1, mp, doy, yoe, doe, epochDay] - dup4 // [mp, 62719, 769, 1, mp, doy, yoe, doe, epochDay] - mul // [mp * 62719, 769, 1, mp, doy, yoe, doe, epochDay] - add // [mp * 62719 + 769, 1, mp, doy, yoe, doe, epochDay] - 0xb // [11, mp * 62719 + 769, 1, mp, doy, yoe, doe, epochDay] - shr // [11 >> mp * 62719 + 769, 1, mp, doy, yoe, doe, epochDay] - dup4 // [doy, 11 >> mp * 62719 + 769, 1, mp, doy, yoe, doe, epochDay] - sub // [doy - 11 >> mp * 62719 + 769, 1, mp, doy, yoe, doe, epochDay] - add // [doy - 11 >> mp * 62719 + 769 + 1, mp, doy, yoe, doe, epochDay] - - // Return stack : // [day, mp, doy, yoe, doe, epochDay] -} - -#define macro GET_MONTH() = takes(0) returns(0) { - // Input stack: [day, mp, doy, yoe, doe, epochDay] - - 0xc // [11,day, mp, doy, yoe, doe, epochDay] - 0x9 // [9,11,day, mp, doy, yoe, doe, epochDay] - dup4 // [mp,9,11,day, mp, doy, yoe, doe, epochDay] - gt // [mp > 9,11,day, mp, doy, yoe, doe, epochDay] - mul // [mp > 9 * 11,day, mp, doy, yoe, doe, epochDay] - 0x3 // [3, mp > 9 * 11,day, mp, doy, yoe, doe, epochDay] - dup4 // [mp, 3, mp > 9 * 11,day, mp, doy, yoe, doe, epochDay] - add // [mp + 3, mp > 9 * 11,day, mp, doy, yoe, doe, epochDay] - sub // [mp + 3 - mp > 9 * 11,day, mp, doy, yoe, doe, epochDay] - - // Return stack : // [month, day, mp, doy, yoe, doe, epochDay] -} - -#define macro GET_YEAR() = takes(0) returns(0) { - // Input stack: [month, day, mp, doy, yoe, doe, epochDay] - - 0x3 // [3, month, day, mp, doy, yoe, doe, epochDay] - dup2 // [month, 3, month, day, mp, doy, yoe, doe, epochDay] - lt // [month < 3, month, day, mp, doy, yoe, doe, epochDay] - 0x190 // [400, month < 3, month, day, mp, doy, yoe, doe, epochDay] - 0x23ab1 // [146097,400, month < 3, month, day, mp, doy, yoe, doe, epochDay] - dup10 // [epochDay, 146097,400, month < 3, month, day, mp, doy, yoe, doe, epochDay] - div // [epochDay / 146097, 400, month < 3, month, day, mp, doy, yoe, doe, epochDay] - mul // [epochDay / 146097 * 400, month < 3, month, day, mp, doy, yoe, doe, epochDay] - dup7 // [yoe, epochDay / 146097 * 400, month < 3, month, day, mp, doy, yoe, doe, epochDay] - add // [yoe+ epochDay / 146097 * 400, month < 3, month, day, mp, doy, yoe, doe, epochDay] - add // [yoe+ epochDay / 146097 * 400 + month < 3, month, day, mp, doy, yoe, doe, epochDay] - - // Return stack : // [year, month, day, mp, doy, yoe, doe, epochDay] -} - -#define macro EPOCH_DAY_TO_DATE() = takes(0) returns(0) { - // Input stack : // [epochDay] - - 0xafa6c // [719468, epochDay] - add // [epochDay] - dup1 // [epochDay, epochDay] - 0x23ab1 // [146097, epochDay,epochDay] - swap1 // [epochDay, 146097,epochDay] - mod // [epochDay % 146097,epochDay] - // [doe,epochDay] - - 0x16d // [365, doe, epochDay] - 0x23ab0 // [146096, 365, doe, epochDay] - dup3 // [doe, 146096, 365, doe, epochDay] - eq // [doe == 146096, 365, doe, epochDay] - 0x5b4 // [1460, doe == 146096, 365, doe, epochDay] - dup4 // [doe, 1460, doe == 146096, 365, doe, epochDay] - div // [doe / 1460, doe == 146096, 365, doe, epochDay] - 0x8eac // [36524, doe / 1460, doe == 146096, 365, doe, epochDay] - dup5 // [doe, 36524, doe / 1460, doe == 146096, 365, doe, epochDay] - div // [doe/ 36524, doe / 1460, doe == 146096, 365, doe, epochDay] - dup5 // [doe, doe/ 36524, doe / 1460, doe == 146096, 365, doe, epochDay] - add // [doe + doe/ 36524, doe / 1460, doe == 146096, 365, doe, epochDay] - sub // [doe + doe/ 36524 - doe / 1460, doe == 146096, 365, doe, epochDay] - sub // [doe + doe/ 36524 - doe / 1460 - doe == 146096, 365, doe, epochDay] - div // [doe + doe/ 36524 - doe / 1460 - doe == 146096 / 365, doe, epochDay] - // [yoe, doe, epochDay] - - 0x64 // [100, yoe, doe, epochDay] - dup2 // [yoe, 100, yoe, doe, epochDay] - div // [yoe / 100, yoe, doe, epochDay] - dup2 // [yoe,yoe / 100, yoe, doe, epochDay] - 0x2 // [2, yoe,yoe / 100, yoe, doe, epochDay] - shr // [yoe >> 2,yoe / 100, yoe, doe, epochDay] - dup3 // [yoe, yoe >> 2,yoe / 100, yoe, doe, epochDay] - 0x16d // [365, yoe, yoe >> 2,yoe / 100, yoe, doe, epochDay] - mul // [365 * yoe, yoe >> 2,yoe / 100, yoe, doe, epochDay] - add // [365 * yoe + yoe >> 2,yoe / 100, yoe, doe, epochDay] - sub // [365 * yoe + yoe >> 2 - yoe / 100, yoe, doe, epochDay] - dup3 // [doe,365 * yoe + yoe >> 2 - yoe / 100, yoe, doe, epochDay] - sub // [doe - 365 * yoe + yoe >> 2 - yoe / 100, yoe, doe, epochDay] - // [doy, yoe, doe, epochDay] - 0x99 // [153, doy, yoe, doe, epochDay] - 0x2 // [2, 153, doy, yoe, doe, epochDay] - dup3 // [doy,2, 153, doy, yoe, doe, epochDay] - 0x5 // [5, doy,2, 153, doy, yoe, doe, epochDay] - mul // [5 * doy,2, 153, doy, yoe, doe, epochDay] - add // [5 * doy + 2, 153, doy, yoe, doe, epochDay] - div // [5 * doy + 2 / 153, doy, yoe, doe, epochDay] - // [mp, doy, yoe, doe, epochDay] - - GET_DAY() // [day, mp, doy, yoe, doe, epochDay] - GET_MONTH() // [month, day, mp, doy, yoe, doe, epochDay] - GET_YEAR() // [year, month, day, mp, doy, yoe, doe, epochDay] - -} - -#define macro TIMESTAMP_TO_DATE() = takes(0) returns(0) { - // Imput stack: [timestamp] - - 0x15180 // [86400, timestamp] - swap1 // [timestamp, 86400] - div // [timestamp / 86400] - - EPOCH_DAY_TO_DATE() // [year, month, day] - - // Return stack: [year, month, day] -} diff --git a/src/utils/__TEMP__vqfnwunrsrlqxsbhtmizflbifjcrmxdqCREATE3.huff b/src/utils/__TEMP__vqfnwunrsrlqxsbhtmizflbifjcrmxdqCREATE3.huff deleted file mode 100644 index 48b6ccf8..00000000 --- a/src/utils/__TEMP__vqfnwunrsrlqxsbhtmizflbifjcrmxdqCREATE3.huff +++ /dev/null @@ -1,177 +0,0 @@ -#define function deploy(bytes32, bytes, uint256) payable returns (address) -#define function getDeployed(bytes32) view returns (address) - -#define macro CREATE_3_DEPLOY_WRAPPER() = takes (0) returns (0) { - 0x44 calldataload // [value] - 0x24 calldataload // [&creationCode, value] - 0x04 calldataload // [salt, &creationCode, value] - CREATE_3_DEPLOY() // [deployed] - 0x00 mstore // [] - 0x20 0x00 return // [] -} - -#define macro CREATE_3_GET_DEPLOYED_WRAPPER() = takes (0) returns (0) { - 0x04 calldataload // [salt] - CREATE_3_GET_DEPLOYED() // [deployed] - 0x00 mstore // [] - 0x20 0x00 return // [] -} - -#define macro MAIN() = { - pc calldataload 0xe0 shr - - dup1 __FUNC_SIG(deploy) eq deploy_jump jumpi - dup1 __FUNC_SIG(getDeployed) eq get_deployed_jump jumpi - - // Exit if selector does not match - 0x00 dup1 revert - - deploy_jump: - CREATE_3_DEPLOY_WRAPPER() - get_deployed_jump: - CREATE_3_GET_DEPLOYED_WRAPPER() -} - -/// @title Create3 -/// @notice SPDX-License-Identifier: MIT -/// @author Maddiaa -/// @author asnared -/// @notice Deploy to deterministic addresses without an initcode factor -/// @notice Adapted from Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/CREATE3.sol) - -#include "./CommonErrors.huff" - - -// Proxy Constants -#define constant PROXY_BYTECODE = 0x67363d3d37363d34f03d5260086018f3 -#define constant PROXY_BYTECODE_HASH = 0x21c35dbe1b344a2488cf3321d6ce542f8e9f305544ff09e4993a62319a497c1f - -//--------------------------------------------------------------------------------// -// Opcode | Opcode + Arguments | Description | Stack View // -//--------------------------------------------------------------------------------// -// 0x36 | 0x36 | CALLDATASIZE | size // -// 0x3d | 0x3d | RETURNDATASIZE | 0 size // -// 0x3d | 0x3d | RETURNDATASIZE | 0 0 size // -// 0x37 | 0x37 | CALLDATACOPY | // -// 0x36 | 0x36 | CALLDATASIZE | size // -// 0x3d | 0x3d | RETURNDATASIZE | 0 size // -// 0x34 | 0x34 | CALLVALUE | value 0 size // -// 0xf0 | 0xf0 | CREATE | newContract // -//--------------------------------------------------------------------------------// -// Opcode | Opcode + Arguments | Description | Stack View // -//--------------------------------------------------------------------------------// -// 0x67 | 0x67XXXXXXXXXXXXXXXX | PUSH8 bytecode | bytecode // -// 0x3d | 0x3d | RETURNDATASIZE | 0 bytecode // -// 0x52 | 0x52 | MSTORE | // -// 0x60 | 0x6008 | PUSH1 08 | 8 // -// 0x60 | 0x6018 | PUSH1 18 | 24 8 // -// 0xf3 | 0xf3 | RETURN | // -//--------------------------------------------------------------------------------// - -/// @notice Deploy a new contract with our pre-made bytecode via CREATE2 -#define macro CREATE_3_DEPLOY() = takes (3) returns (1) { - // Input Stack: [salt, &creationCode, value] - // Output Stack: [deployed] - - // Create the proxy - dup1 0x10 // [size, salt, salt, &creationCode, value] - - // Shift the proxy bytecode left - [PROXY_BYTECODE] // [bytecode, size, salt, salt, &creationCode, value, bytecode] - 0x80 shl // [RIGHTPAD(bytecode), size, salt, salt, &creationCode, value, bytecode] - 0x00 mstore // [size, salt, salt, &creationCode, value] - 0x00 // [offset, size, salt, salt, &creationCode, value] - 0x00 // [value, offset, size, salt, salt, &creationCode, value] - create2 // [address, salt, &creationCode, value] - - // Check the address of of the proxy is not null - dup1 iszero // [address == 0, address, salt, &creationCode, value] - deployment_failed jumpi // [address, salt, &creationCode, value] - - // Load the length of the creation code - dup3 0x04 add calldataload // [creationCode.length, address, salt, &creationCode, value] - - // Copy the code from calldata to memory at memory position 0x20 - dup1 0x05 shl // [size, creationCode.length, address, salt, &creationCode, value] - dup5 0x24 add // [calldataOffset, size, creationCode.length, address, salt, &creationCode, value] - 0x20 // [destOffset, calldataOffset, size, creationCode.length, address, salt, &creationCode, value] - calldatacopy // [creationCode.length, address, salt, &creationCode, value] - - // Call the proxy with the creation code - 0x20 // [retSize, creationCode.length, address, salt, &creationCode, value] - 0x00 // [retOffset, retSize, creationCode.length, address, salt, &creationCode, value] - dup3 // [argSize, retOffset, retSize, creationCode.length, address, salt, &creationCode, value] - 0x20 // [argOffset, argSize, retOffset, retSize, creationCode.length, address, salt, &creationCode, value] - dup9 // [value, argOffset, argSize, retOffset, retSize, creationCode.length, address, salt, &creationCode, value] - dup7 // [to, value, argOffset, argSize, retOffset, retSize, creationCode.length, address, salt, &creationCode, value] - gas // [gas, to, value, argOffset, argSize, retOffset, retSize, creationCode.length, address, salt, &creationCode, value] - call // [success, creationCode.length, address, salt, &creationCode, value] - iszero // [success == 0, creationCode.length, address, salt, &creationCode, value] - init_failed jumpi // [creationCode.length, address, salt, &creationCode, value] - - // Get the deployed contract using the salt and make sure it has code at the address - dup3 CREATE_3_GET_DEPLOYED() // [deployed, creationCode.length, address, salt, &creationCode, value] - dup1 extcodesize // [deployed == 0, deployed, creationCode.length, address, salt, &creationCode, value] - iszero init_failed jumpi // [deployed, creationCode.length, address, salt, &creationCode, value] - - // Clean up stack and return - swap5 pop pop pop pop pop // [deployed] - done jump - - deployment_failed: - DEPLOYMENT_FAILED(0x00) - init_failed: - INITIALIZATION_FAILED(0x00) - - done: -} - -#define macro CREATE_3_GET_DEPLOYED() = takes (1) returns (1) { - // Input Stack : [salt] - // Output Stack: [deployed_address] - - // Store 0xff | (right_padded_address >> 1) in memory - __RIGHTPAD(0xff) // [rightpad(0xff), salt] - address 0x58 shl // [rightpad(address), rightpad(0xff), salt] - or // [[0xff][address], salt] - 0x00 mstore // [salt] - - // Store the salt in memory at position 0x15 - 0x15 mstore // [] - - // Store the hash in memory at 0x35 - [PROXY_BYTECODE_HASH] // [hash] - 0x35 mstore // [] - - // Hash the memory from 0x00:0x55 - 0x55 0x00 sha3 // [keccak] - - // ---------------------------------------- // - // Memory Layout // - // ---------------------------------------- // - // prefix | address | nonce | empty // - // 0xd694 | | 01 | 000..000 // - // ---------------------------------------- // - - // 0xd6 = 0xc0 (short RLP prefix) + 0x16 (length of: 0x94 ++ proxy ++ 0x01) - // 0x94 = 0x80 + 0x14 (0x14 = the length of an address, 20 bytes, in hex) - - // Clear the top 10 bytes of the hash - 0x60 shl 0x10 shr // [proxy_address] - - // return rpl encoded - __RIGHTPAD(0xd694) // [0xd694, proxy_address] - or // [ [0xd694][proxy_address] ] - - // Append a 0x01 to the end of the address - - 0x01 0x48 shl // [0x01 << 9, [0xd694][proxy_address]] - or // [ [0xd694][proxy_address][01] ] - - // Hash the packed encoding in memory position 0x00 - 0x00 mstore // [] - 0x17 0x00 sha3 // [hash] - - // Clear the top 12 bytes using shifts - 0x60 shl 0x60 shr // [proxy_address] -} diff --git a/src/utils/__TEMP__wiecgaaxwkphsyuihxlbouwaxpbkeiagInsertionSort.huff b/src/utils/__TEMP__wiecgaaxwkphsyuihxlbouwaxpbkeiagInsertionSort.huff deleted file mode 100644 index 2959ef82..00000000 --- a/src/utils/__TEMP__wiecgaaxwkphsyuihxlbouwaxpbkeiagInsertionSort.huff +++ /dev/null @@ -1,100 +0,0 @@ -/// SPDX-License-Identifier: MIT - -/// @notice Insertion Sort Function -#define function insertionSort(uint256[]) nonpayable returns (uint256[]) - -/// @notice Performs insertion sort on raw calldata -#define macro INSERTION_SORT() = takes (0) returns (0) { - SORT() // [offset, arrSize] - return // [] -} - -/// @notice The contract entrypoint -#define macro MAIN() = takes(0) returns (0) { - returndatasize calldataload 0xe0 shr // [selector] - - // notice: we don't need to duplicate the selector here - // since the selector is consumed and only used once - __FUNC_SIG(insertionSort) eq jumpSort jumpi // [] - - // Reverts if selector not present. - returndatasize returndatasize revert - - jumpSort: - INSERTION_SORT() -} - - -/// @title Sort -/// @notice SPDX-License-Identifier: MIT -/// @author tanim0la -/// @notice Insertion sort implementation - -/* MACRO */ -/// @notice Returns two items `offSet` and `arrSize` -#define macro SORT() = takes (0) returns (2) { - - 0x04 calldatasize sub // [arrSize] - dup1 // [arrSize, arrSize] - 0x04 // [offset, arrSize, arrSize] - 0x40 // [mem, offset, arrSize, arrSize] - calldatacopy // [arrSize] - - 0x01 returndatasize mstore // i = 1 - 0x60 mload // [len, arrSize] - - // For loop - start: - // End if i == len - returndatasize mload // [i, len, arrSize] - dup2 dup2 // [i, len, i, len, arrSize] - eq end jumpi - - // Assign i to j - 0x20 mstore // [len, arrSize] - - // While loop - while: - returndatasize // [0, len, arrSize] - 0x20 mload dup2 dup2 // [j, 0, j, 0, len, arrSize] - gt // [cndt1, j, 0, len, arrSize] - - - // 0x80 + (0x20 * j) - dup2 0x20 mul 0x80 add // [mem[arr[j]], cndt1, j, 0, len, arrSize] - - // 0x80 + (0x20 * (j - 0x01)) - 0x01 dup4 sub 0x20 mul 0x80 add // [mem[arr[j - i]], mem[arr[j]], cndt1, j, 0, len, arrSize] - dup2 // [mem[arr[j]], mem[arr[j - 1]], mem[arr[j]], cndt1, j, 0, len, arrSize] - - mload // [arr[j], mem[arr[j - 1]], mem[arr[j]], cndt1, j, 0, len, arrSize] - dup2 mload // [arr[j - 1], arr[j], mem[arr[j - 1]], mem[arr[j]], cndt1, j, 0, len, arrSize] - - gt dup4 // [cndt1, cndt2, mem[arr[j - 1]], mem[arr[j]], cndt1, j, 0, len, arrSize] - and continueWhile jumpi // [mem[arr[j - 1]], mem[arr[j]], cndt1, j, 0, len, arrSize] - - // Go to continue - pop pop pop pop pop // [len, arrSize] - - // Increment i++ - returndatasize mload 0x01 add // [i + 1, len, arrSize] - returndatasize mstore start jump // [len, arrSize] - - // While block - continueWhile: - // arr[j - 1] = arr[j] - dup1 mload dup3 mload // [arr[j], arr[j - i], mem[arr[j - 1]], mem[arr[j]], cndt1, j, 0, len, arrSize] - dup3 mstore // [arr[j - 1], mem[arr[j - 1]], mem[arr[j]], cndt1, j, 0, len, arrSize] - - // arr[j] = arr[j - 1] - dup3 mstore // [mem[arr[j - 1], mem[arr[j]], cndt1, j, 0, len, arrSize] - - pop pop pop // [j, 0, len, arrSize] - - // Decrement j-- - 0x01 dup2 sub // [j - 1 ,j, 0, len, arrSize] - 0x20 mstore pop pop // [len, arrSize] - while jump - end: - pop pop 0x40 // [offset, arrSize] -} diff --git a/src/utils/__TEMP__wtgpdnpvqgkfupsuzejejufgqepcfpeyDateTimeLib.huff b/src/utils/__TEMP__wtgpdnpvqgkfupsuzejejufgqepcfpeyDateTimeLib.huff deleted file mode 100644 index 04bae5ed..00000000 --- a/src/utils/__TEMP__wtgpdnpvqgkfupsuzejejufgqepcfpeyDateTimeLib.huff +++ /dev/null @@ -1,517 +0,0 @@ -/* Functions */ -#define function weekday(uint256) nonpayable returns (uint256) -#define function isLeapYear(uint256) nonpayable returns (bool) -#define function daysInMonth(uint256,uint256) nonpayable returns (uint256) -#define function dateToEpochDay(uint256,uint256,uint256) nonpayable returns (uint256) -#define function dateToTimestamp(uint256,uint256,uint256) nonpayable returns (uint256) -#define function dateTimeToTimestamp(uint256,uint256,uint256,uint256,uint256,uint256) nonpayable returns (uint256) -#define function nthWeekdayInMonthOfYearTimestamp(uint256, uint256,uint256,uint256) nonpayable returns (uint256) -#define function epochDayToDate(uint256) nonpayable returns (uint256,uint256,uint256) -#define function timestampToDate(uint256) nonpayable returns (uint256,uint256,uint256) - -/* Wrapper Macros */ -#define macro WEEKDAY_WRAPPER() = takes (0) returns (0) { - 0x04 calldataload // [timestamp] - WEEKDAY() // [result] - 0x00 mstore // [] - 0x20 0x00 return // [] - } - -#define macro IS_LEAP_YEAR_WRAPPER() = takes (0) returns (0) { - 0x04 calldataload // [timestamp] - IS_LEAP_YEAR() // [result] - 0x00 mstore // [] - 0x20 0x00 return // [] - } - -#define macro DAYS_IN_MONTH_WRAPPER() = takes (0) returns (0) { - 0x04 calldataload // [year] - 0x24 calldataload // [month, year] - DAYS_IN_MONTH() // [result] - 0x00 mstore // [] - 0x20 0x00 return // [] - } - -#define macro DATE_TO_EPOCH_DAY_WRAPPER() = takes (0) returns (0) { - 0x04 calldataload // [year] - 0x24 calldataload // [month, year] - 0x44 calldataload // [day, month, year] - DATE_TO_EPOCH_DAY() // [result] - 0x00 mstore // [] - 0x20 0x00 return // [] - } - - #define macro DATE_TO_TIMESTAMP_WRAPPER() = takes (0) returns (0) { - 0x04 calldataload // [year] - 0x24 calldataload // [month, year] - 0x44 calldataload // [day, month, year] - DATE_TO_TIMESTAMP() // [result] - 0x00 mstore // [] - 0x20 0x00 return // [] - } - - #define macro DATE_TIME_TO_TIMESTAMP_WRAPPER() = takes (0) returns (0) { - 0x04 calldataload // [year] - 0x24 calldataload // [month, year] - 0x44 calldataload // [day, month, year] - 0x64 calldataload // [seconds, day, month, year] - 0x84 calldataload // [minutes, seconds, day, month, year] - 0xa4 calldataload // [hours, minutes, seconds, day, month, year] - DATE_TIME_TO_TIMESTAMP() // [result] - 0x00 mstore // [] - 0x20 0x00 return // [] - } - - #define macro EPOCH_DAY_TO_DATE_WRAPPER() = takes (0) returns (0) { - 0x04 calldataload // [epochDay] - EPOCH_DAY_TO_DATE() // [year, month, day] - 0x00 mstore // [month, day] - 0x20 mstore // [day] - 0x40 mstore // [] - 0x60 0x00 return // [] - } - - #define macro TIMESTAMP_TO_DATE_WRAPPER() = takes (0) returns (0) { - 0x04 calldataload // [timestamp] - TIMESTAMP_TO_DATE() // [year, month, day] - 0x00 mstore // [month, day] - 0x20 mstore // [day] - 0x40 mstore // [] - 0x60 0x00 return // [] - } - - - - #define macro NTH_WEEKDAY_IN_MONTH_OF_YEAR_TIMESTAMP_WRAPPER() = takes (0) returns (0) { - 0x04 calldataload // [year] - 0x24 calldataload // [month, year] - 0x44 calldataload // [n, month, year] - 0x64 calldataload // [wd, n, month, year] - NTH_WEEKDAY_IN_MONTH_OF_YEAR_TIMESTAMP() // [result] - 0x00 mstore // [] - 0x20 0x00 return // [] - } - -/* Function Dispatcher */ -#define macro MAIN() = takes (0) returns (0) { - // Identify which function is being called. - 0x00 calldataload - - // Extract the function singature - 0xe0 shr - - // Jump table - dup1 __FUNC_SIG(weekday) eq weekday jumpi - dup1 __FUNC_SIG(isLeapYear) eq isLeapYear jumpi - dup1 __FUNC_SIG(daysInMonth) eq daysInMonth jumpi - dup1 __FUNC_SIG(dateToEpochDay) eq dateToEpochDay jumpi - dup1 __FUNC_SIG(epochDayToDate) eq epochDayToDate jumpi - dup1 __FUNC_SIG(timestampToDate) eq timestampToDate jumpi - dup1 __FUNC_SIG(dateToTimestamp) eq dateToTimestamp jumpi - dup1 __FUNC_SIG(dateTimeToTimestamp) eq dateTimeToTimestamp jumpi - dup1 __FUNC_SIG(nthWeekdayInMonthOfYearTimestamp) eq nthWeekdayInMonthOfYearTimestamp jumpi - - - weekday: - WEEKDAY_WRAPPER() - - isLeapYear: - IS_LEAP_YEAR_WRAPPER() - - daysInMonth: - DAYS_IN_MONTH_WRAPPER() - - dateToEpochDay: - DATE_TO_EPOCH_DAY_WRAPPER() - - epochDayToDate: - EPOCH_DAY_TO_DATE_WRAPPER() - - timestampToDate: - TIMESTAMP_TO_DATE_WRAPPER() - - dateToTimestamp: - DATE_TO_TIMESTAMP_WRAPPER() - - dateTimeToTimestamp: - DATE_TIME_TO_TIMESTAMP_WRAPPER() - - nthWeekdayInMonthOfYearTimestamp: - NTH_WEEKDAY_IN_MONTH_OF_YEAR_TIMESTAMP_WRAPPER() - -} - - - - -/// @title DateTimeLib -/// @notice SPDX-License-Identifier: MIT -/// @author PraneshASP -/// @notice Library for date time operations. -/// @notice Adapted from Solady (https://github.com/Vectorized/solady/blob/main/src/utils/DateTimeLib.so) - -/// Conventions: -/// --------------------------------------------------------------------+ -/// Unit | Range | Notes | -/// --------------------------------------------------------------------| -/// timestamp | 0..0x1e18549868c76ff | Unix timestamp. | -/// epochDay | 0..0x16d3e098039 | Days since 1970-01-01. | -/// year | 1970..0xffffffff | Gregorian calendar year. | -/// month | 1..12 | Gregorian calendar month. | -/// day | 1..31 | Gregorian calendar day of month. | -/// weekday | 1..7 | The day of the week (1-indexed). | -/// --------------------------------------------------------------------+ -/// All timestamps of days are rounded down to 00:00:00 UTC. - -//////////////////////////////////////////////////////////////// -// Logic // -//////////////////////////////////////////////////////////////// - -/// @dev Returns day of the week (Monday is indicated as 1 and so on) -#define macro WEEKDAY() = takes (0) returns (0) { - // Formula: ((timestamp / 86400 + 3) % 7) + 1; - - // Input Stack: [timestamp(t)] - - 0x15180 // [86400, t] - swap1 // [t,86400] - div // [t/86400] - 0x03 // [3, t/86400] - add // [3 + t/86400] - 0x07 // [7, (3+t/86400)] - swap1 // [(t/86400 + 3), 7] - mod // [(t/86400 + 3) % 7] - 0x01 // [1, (t/86400 + 3)%7] - add // [1 + (t/86400 + 3)%7] - - // Return stack: [result] -} - -#define macro IS_LEAP_YEAR() = takes (0) returns (0) { - // Condition 1, C1 = year % 4 == 0 - // Condition 2, C2 = year % 100 != 0 - // Condition 3, C3 = year % 400 == 0 - - // Formula: C1 && (C2||C3) - - // Input stack: [year] - - // Calculate C2 - 0x64 // [100, year] - dup2 // [year, 100, year] - mod // [year % 100, year] - iszero // [year % 100 == 0, year] - not // [C2, year] - - // Calculate C1 - 0x04 // [4, C2, year] - dup3 // [year, 4, C2, year] - mod // [year % 4, C2, year] - iszero // [C1, C2, year] - - // Calculate C3 - swap2 // [year, C2, C1] - 0x190 // [400, year, C2, C1] - swap1 // [year, 400, C2, C1] - mod // [year % 400, C2, C1] - iszero // [C3, C2, C1] - or // [(C2||C3), C1] - and // [(C2||C3) && C1] - - // Return stack: [result] -} - - -#define macro DAYS_IN_MONTH() = takes (0) returns (0) { - // Input Stack : [month, year] - - // Push days in month map: [31,28,31,30,31,30,31,31,30,31,30,31] - 0x1F1C1F1E1F1E1F1F1E1F1E1F // [daysInMonthMap, month, year] - - dup2 // [month, daysInMonthMap, month, year] - 0x13 // [19, month, daysInMonthMap, month, year] - add // [monthOffset, daysInMonthMap, month, year] - byte // [daysInMonth, month, year] - swap2 // [year, month, daysInMonth] - IS_LEAP_YEAR() // [isleap(year), month, daysInMonth] - swap1 // [month, isleap(year), daysInMonth] - 0x02 // [2, month, isleap(year), daysInMonth] - eq // [2 == month, isleap(year), daysInMonth] - and // [2==month && isleap(year), daysInMonth] - add // [2==month && isleap(year) + daysInMonth] - - // Return stack: [result] -} - - -#define macro DATE_TO_EPOCH_DAY() = takes (0) returns (0) { - // Input stack : [d, m, y] - swap2 // [y,m,d] - 0x3 // [3,y,m,d] - dup3 // [m,3,y,m,d] - lt // [m < 3, y,m,d] - swap1 // [y, m<3, m,d] - sub // [y-m<3,m,d] - // y = y - (m<3) - /// doy construction - dup3 // [d, y,m,d] - 0x301 // [769,d, y, m, d] - 0xc // [12, 769,d, y, m, d] - 0x9 // [9,12, 769,d, y, m, d] - dup6 // [m, 9,12, 769,d, y, m, d] - add // [m + 9,12, 769, d, y, m, d] - mod // [m + 9 % 12, 769, d, y, m, d] - 0xf4ff // [62719, m + 9 % 12, 769,d, y, m, d] - mul // [62719 * m + 9 % 12, 769, d, y, m, d] - add // [62719 * m + 9 % 12 + 769,d, y, m, d] - 0xb // [11, 62719 * m + 9 % 12 + 769, d, y, m, d] - shr // [62719 * m + 9 % 12 + 769 >> 11, d, y, m, d] - add // [62719 * m + 9 % 12 + 769 >> 11 + d, y, m, d] - // [doy, y,m,d] - - /// yoe construction - 0x190 // [400,doy,y,m,d] - dup3 // [y,400, doy,y,m,d] - mod // [y%400, doy, y, m,d] - // [yoe, doy, y, m, d] - /// doe construction - 0x64 // [100, yoe, doy, y, m, d] - dup2 // [yoe, 100, yoe, doy, y, m, d] - div // [yoe / 100, yoe, doy, y, m, d] - dup3 // [doy, yoe / 100, yoe, doy, y, m, d] - dup3 // [yoe, doy, yoe / 100, yoe, doy, y, m, d] - 0x2 // [2, yoe, doy, yoe / 100, yoe, doy, y, m, d] - shr // [yoe >> 2, doy, yoe / 100, yoe, doy, y, m, d] - 0x16d // [365, yoe >> 2, doy, yoe / 100, yoe, doy, y, m, d] - dup5 // [yoe, 365, yoe >> 2, doy, yoe / 100, yoe, doy, y, m, d] - mul // [yoe * 365, yoe >> 2, doy, yoe / 100, yoe, doy, y, m, d] - add // [yoe * 365 + yoe >> 2, doy, yoe / 100, yoe, doy, y, m, d] - add // [yoe * 365 + yoe >> 2 + doy, yoe / 100, yoe, doy, y, m, d] - sub // [yoe * 365 + yoe >> 2 + doy - yoe / 100, yoe, doy, y, m, d] - // [doe, yoe, doy, y, m, d] - - 0xafa6d // [719469, doe, yoe, doy, y, m, d] - swap1 // [doe, 719469, yoe, doy, y, m, d] - 0x23ab1 // [146097, doe, 719469, yoe, doy, y, m, d] - 0x190 // [400, 146097, doe, 719469, yoe, doy, y, m, d] - dup7 // [y, 400, 146097, doe, 719469, yoe, doy, y, m, d] - div // [y / 400, 146097, doe, 719469, yoe, doy, y, m, d] - mul // [y / 400 * 146097, doe, 719469, yoe, doy, y, m, d] - add // [y / 400 * 146097 + doe, 719469, yoe, doy, y, m, d] - sub // [y / 400 * 146097 + doe - 719469, yoe, doy, y, m, d] - - // Clear stack - swap5 - pop pop pop pop pop - - // Return stack: // [result] -} - -#define macro DATE_TO_TIMESTAMP() = takes (0) returns (0) { - // Input stack = [d, m, y] - DATE_TO_EPOCH_DAY() // [epochDay] - 0x15180 // [86400, epochDay] - mul // [86400 * epochDay] - // Return stack: // [timestamp] -} - - -#define macro NTH_WEEKDAY_IN_MONTH_OF_YEAR_TIMESTAMP() = takes (0) returns (0) { - // Input stack: [wd, n, m, y] - dup4 // [y, wd, n, m, y] - dup4 // [m, y, wd, n, m, y] - 0x1 // [1, m, y, wd, n, m, y] - DATE_TO_EPOCH_DAY() // [d, wd, n, m, y] - - dup5 // [y, d, wd, n, m, y] - dup5 // [m, y, d, wd, n, m, y] - DAYS_IN_MONTH() // [md, d, wd, n, m, y] - - 0x1 // [1, md, d, wd, n, m, y] - 0x7 // [7, 1, md, d, wd, n, m, y] - 0x3 // [3, 7, 1, md, d, wd, n, m, y] - dup5 // [d, 3, 7, 1, md, d, wd, n, m, y] - add // [d + 3, 7, 1, md, d, wd, n, m, y] - mod // [d + 3 % 7, 1, md, d, wd, n, m, y] - add // [d + 3 % 7 + 1, md, d, wd, n, m, y] - dup4 // [wd, d + 3 % 7 + 1, md, d, wd, n, m, y] - sub // [wd - d + 3 % 7 + 1, md, d, wd, n, m, y] - // [diff, md, d, wd, n, m, y] - - 0x7 // [7, diff, md, d, wd, n, m, y] - 0x6 // [6, 7, diff, md, d, wd, n, m, y] - dup3 // [diff, 6, 7, diff, md, d, wd, n, m, y] - gt // [diff > 6, 7, diff, md, d, wd, n, m, y] - mul // [diff > 6 * 7, diff, md, d, wd, n, m, y] - add // [diff > 6 * 7 + diff, md, d, wd, n, m, y] - 0x7 // [7,diff > 6 * 7 + diff, md, d, wd, n, m, y] - 0x1 // [1, 7, diff > 6 * 7 + diff, md, d, wd, n, m, y] - dup7 // [n, 1, 7,diff > 6 * 7 + diff, md, d, wd, n, m, y] - sub // [n - 1, 7,diff > 6 * 7 + diff, md, d, wd, n, m, y] - mul // [n - 1 * 7,diff > 6 * 7 + diff, md, d, wd, n, m, y] - add // [n - 1 * 7 + diff > 6 * 7 + diff, md, d, wd, n, m, y] - // [date, md, d, wd, n, m, y] - - swap4 // [n, md, d, wd, date, m, y] - iszero // [n==0, md, d,wd, date, m, y] - iszero // [((n==0)==0), md, d, wd, date, m, y] - swap1 // [md,((n==0)==0),d,wd, date,m,y] - dup5 // [date, md,((n==0)==0),d,wd, date,m,y] - lt // [date < md,((n==0)==0),d,wd,date,m,y] - and // [date < md && ((n==0)==0),d,wd,date,m,y] - swap1 // [d, date < md && ((n==0)==0),wd, date,m,y] - dup4 // [date, d, date < md && ((n==0)==0),wd, date,m,y] - add // [date + d, date < md && ((n==0)==0),wd,date,m,y] - 0x15180 // [86400, date + d, date < md && ((n==0)==0),wd,date,m,y] - mul // [86400 * date + d, date < md && ((n==0)==0),wd, date,m,y] - mul // [86400 * date + d * date < md && ((n==0)==0),wd,date,m,y] - - // clear stack - swap4 - pop pop - pop pop - - // Return stack: // [result] -} - - - -#define macro DATE_TIME_TO_TIMESTAMP() = takes(0) returns(0) { - // Input stack : [day, month ,year ,hour,min,sec] - - DATE_TO_EPOCH_DAY() // [epochDay, hour, min, sec] - 0x15180 // [86400,epochDay, hour, min, sec] - mul // [86400*epochDay, hour, min, sec] - swap1 // [hour, 86400*epochDay, min, sec] - 0xe10 // [3600,hour, 86400*epochDay, min, sec] - mul // [3600*hour, 86400*epochDay, min, sec] - swap2 // [min, 86400*epochDay, 3600*hour, sec] - 0x3c // [60,min, 86400*epochDay, 3600*hour, sec] - mul // [60 * min, 86400*epochDay, 3600*hour, sec] - add // [60 * min + 86400*epochDay, 3600*hour, sec] - add // [60 * min + 86400*epochDay + 3600*hour, sec] - add // [60 * min + 86400*epochDay + 3600*hour + sec] - - // Return stack: [result] -} - -#define macro GET_DAY() = takes(0) returns(0) { - // Input stack: [mp, doy, yoe, doe, epochDay] - - 0x1 // [1, mp, doy, yoe, doe, epochDay] - 0x301 // [769, 1, mp, doy, yoe, doe, epochDay] - 0xf4ff // [62719, 769, 1, mp, doy, yoe, doe, epochDay] - dup4 // [mp, 62719, 769, 1, mp, doy, yoe, doe, epochDay] - mul // [mp * 62719, 769, 1, mp, doy, yoe, doe, epochDay] - add // [mp * 62719 + 769, 1, mp, doy, yoe, doe, epochDay] - 0xb // [11, mp * 62719 + 769, 1, mp, doy, yoe, doe, epochDay] - shr // [11 >> mp * 62719 + 769, 1, mp, doy, yoe, doe, epochDay] - dup4 // [doy, 11 >> mp * 62719 + 769, 1, mp, doy, yoe, doe, epochDay] - sub // [doy - 11 >> mp * 62719 + 769, 1, mp, doy, yoe, doe, epochDay] - add // [doy - 11 >> mp * 62719 + 769 + 1, mp, doy, yoe, doe, epochDay] - - // Return stack : // [day, mp, doy, yoe, doe, epochDay] -} - -#define macro GET_MONTH() = takes(0) returns(0) { - // Input stack: [day, mp, doy, yoe, doe, epochDay] - - 0xc // [11,day, mp, doy, yoe, doe, epochDay] - 0x9 // [9,11,day, mp, doy, yoe, doe, epochDay] - dup4 // [mp,9,11,day, mp, doy, yoe, doe, epochDay] - gt // [mp > 9,11,day, mp, doy, yoe, doe, epochDay] - mul // [mp > 9 * 11,day, mp, doy, yoe, doe, epochDay] - 0x3 // [3, mp > 9 * 11,day, mp, doy, yoe, doe, epochDay] - dup4 // [mp, 3, mp > 9 * 11,day, mp, doy, yoe, doe, epochDay] - add // [mp + 3, mp > 9 * 11,day, mp, doy, yoe, doe, epochDay] - sub // [mp + 3 - mp > 9 * 11,day, mp, doy, yoe, doe, epochDay] - - // Return stack : // [month, day, mp, doy, yoe, doe, epochDay] -} - -#define macro GET_YEAR() = takes(0) returns(0) { - // Input stack: [month, day, mp, doy, yoe, doe, epochDay] - - 0x3 // [3, month, day, mp, doy, yoe, doe, epochDay] - dup2 // [month, 3, month, day, mp, doy, yoe, doe, epochDay] - lt // [month < 3, month, day, mp, doy, yoe, doe, epochDay] - 0x190 // [400, month < 3, month, day, mp, doy, yoe, doe, epochDay] - 0x23ab1 // [146097,400, month < 3, month, day, mp, doy, yoe, doe, epochDay] - dup10 // [epochDay, 146097,400, month < 3, month, day, mp, doy, yoe, doe, epochDay] - div // [epochDay / 146097, 400, month < 3, month, day, mp, doy, yoe, doe, epochDay] - mul // [epochDay / 146097 * 400, month < 3, month, day, mp, doy, yoe, doe, epochDay] - dup7 // [yoe, epochDay / 146097 * 400, month < 3, month, day, mp, doy, yoe, doe, epochDay] - add // [yoe+ epochDay / 146097 * 400, month < 3, month, day, mp, doy, yoe, doe, epochDay] - add // [yoe+ epochDay / 146097 * 400 + month < 3, month, day, mp, doy, yoe, doe, epochDay] - - // Return stack : // [year, month, day, mp, doy, yoe, doe, epochDay] -} - -#define macro EPOCH_DAY_TO_DATE() = takes(0) returns(0) { - // Input stack : // [epochDay] - - 0xafa6c // [719468, epochDay] - add // [epochDay] - dup1 // [epochDay, epochDay] - 0x23ab1 // [146097, epochDay,epochDay] - swap1 // [epochDay, 146097,epochDay] - mod // [epochDay % 146097,epochDay] - // [doe,epochDay] - - 0x16d // [365, doe, epochDay] - 0x23ab0 // [146096, 365, doe, epochDay] - dup3 // [doe, 146096, 365, doe, epochDay] - eq // [doe == 146096, 365, doe, epochDay] - 0x5b4 // [1460, doe == 146096, 365, doe, epochDay] - dup4 // [doe, 1460, doe == 146096, 365, doe, epochDay] - div // [doe / 1460, doe == 146096, 365, doe, epochDay] - 0x8eac // [36524, doe / 1460, doe == 146096, 365, doe, epochDay] - dup5 // [doe, 36524, doe / 1460, doe == 146096, 365, doe, epochDay] - div // [doe/ 36524, doe / 1460, doe == 146096, 365, doe, epochDay] - dup5 // [doe, doe/ 36524, doe / 1460, doe == 146096, 365, doe, epochDay] - add // [doe + doe/ 36524, doe / 1460, doe == 146096, 365, doe, epochDay] - sub // [doe + doe/ 36524 - doe / 1460, doe == 146096, 365, doe, epochDay] - sub // [doe + doe/ 36524 - doe / 1460 - doe == 146096, 365, doe, epochDay] - div // [doe + doe/ 36524 - doe / 1460 - doe == 146096 / 365, doe, epochDay] - // [yoe, doe, epochDay] - - 0x64 // [100, yoe, doe, epochDay] - dup2 // [yoe, 100, yoe, doe, epochDay] - div // [yoe / 100, yoe, doe, epochDay] - dup2 // [yoe,yoe / 100, yoe, doe, epochDay] - 0x2 // [2, yoe,yoe / 100, yoe, doe, epochDay] - shr // [yoe >> 2,yoe / 100, yoe, doe, epochDay] - dup3 // [yoe, yoe >> 2,yoe / 100, yoe, doe, epochDay] - 0x16d // [365, yoe, yoe >> 2,yoe / 100, yoe, doe, epochDay] - mul // [365 * yoe, yoe >> 2,yoe / 100, yoe, doe, epochDay] - add // [365 * yoe + yoe >> 2,yoe / 100, yoe, doe, epochDay] - sub // [365 * yoe + yoe >> 2 - yoe / 100, yoe, doe, epochDay] - dup3 // [doe,365 * yoe + yoe >> 2 - yoe / 100, yoe, doe, epochDay] - sub // [doe - 365 * yoe + yoe >> 2 - yoe / 100, yoe, doe, epochDay] - // [doy, yoe, doe, epochDay] - 0x99 // [153, doy, yoe, doe, epochDay] - 0x2 // [2, 153, doy, yoe, doe, epochDay] - dup3 // [doy,2, 153, doy, yoe, doe, epochDay] - 0x5 // [5, doy,2, 153, doy, yoe, doe, epochDay] - mul // [5 * doy,2, 153, doy, yoe, doe, epochDay] - add // [5 * doy + 2, 153, doy, yoe, doe, epochDay] - div // [5 * doy + 2 / 153, doy, yoe, doe, epochDay] - // [mp, doy, yoe, doe, epochDay] - - GET_DAY() // [day, mp, doy, yoe, doe, epochDay] - GET_MONTH() // [month, day, mp, doy, yoe, doe, epochDay] - GET_YEAR() // [year, month, day, mp, doy, yoe, doe, epochDay] - -} - -#define macro TIMESTAMP_TO_DATE() = takes(0) returns(0) { - // Imput stack: [timestamp] - - 0x15180 // [86400, timestamp] - swap1 // [timestamp, 86400] - div // [timestamp / 86400] - - EPOCH_DAY_TO_DATE() // [year, month, day] - - // Return stack: [year, month, day] -} diff --git a/src/utils/__TEMP__xllvhpaiggcjojltrdelmvtrrnvpcuusPausable.huff b/src/utils/__TEMP__xllvhpaiggcjojltrdelmvtrrnvpcuusPausable.huff deleted file mode 100644 index 9a967559..00000000 --- a/src/utils/__TEMP__xllvhpaiggcjojltrdelmvtrrnvpcuusPausable.huff +++ /dev/null @@ -1,131 +0,0 @@ -#define function isPaused() view returns (bool) -#define function pause() nonpayable returns () -#define function unpause() nonpayable returns () - - -#define macro CONSTRUCTOR() = takes (0) returns (0) { - PAUSABLE_CONSTRUCTOR() -} - - -#define macro IS_PAUSED_WRAPPER() = takes (0) returns (0) { - PAUSABLE_IS_PAUSED() -} - -#define macro PAUSE_WRAPPER() = takes (0) returns (0) { - PAUSABLE_PAUSE() -} - -#define macro UNPAUSE_WRAPPER() = takes (0) returns (0) { - PAUSABLE_UNPAUSE() -} - - -#define macro MAIN() = takes (0) returns (0) { - pc calldataload 0xe0 shr // [sig] - - dup1 __FUNC_SIG(pause) eq pause jumpi - dup1 __FUNC_SIG(unpause) eq unpause jumpi - dup1 __FUNC_SIG(isPaused) eq is_paused jumpi - - 0x00 dup1 revert - - pause: - PAUSE_WRAPPER() - unpause: - UNPAUSE_WRAPPER() - is_paused: - IS_PAUSED_WRAPPER() -} - -/// @title Pausable -/// @notice SPDX-License-Identifier: MIT -/// @author zarf.eth -/// @notice A Pausable implementation - - -// Interface - -/// @notice returns whether the contract is paused -#define function isPaused() view returns (bool) - -/// @notice Pauses the contract -/// @dev Only callable when the contract is unpaused. -#define function pause() nonpayable returns () - -/// @notice Unpauses the contract -/// @dev Only callable when the contract is paused. -#define function unpause() nonpayable returns () - -/// @notice Emitted when contract is paused. -#define event Paused(address) - -/// @notice Emitted when contract is unpaused. -#define event Unpaused(address) - - -// Storage - -/// @notice Paused Storage Slot -#define constant PAUSED_SLOT = FREE_STORAGE_POINTER() - -/// @notice Unpaused representation -#define constant NOT_PAUSED = 0x01 - -/// @notice Paused representation -#define constant PAUSED = 0x02 - - -/// @notice Pausable constructor -#define macro PAUSABLE_CONSTRUCTOR() = takes (0) returns (0) { - [NOT_PAUSED] [PAUSED_SLOT] sstore // [] -} - -/// @notice whenNotPaused modifier -#define macro WHEN_NOT_PAUSED_MODIFIER() = takes (0) returns (0) { - [PAUSED_SLOT] sload // [isPaused] - [NOT_PAUSED] eq when_not_paused jumpi // [] - 0x00 dup1 revert // [] - when_not_paused: // [] -} - -/// @notice whenPaused modifier -#define macro WHEN_PAUSED_MODIFIER() = takes (0) returns (0) { - [PAUSED_SLOT] sload // [isPaused] - [PAUSED] eq when_paused jumpi // [] - 0x00 dup1 revert // [] - when_paused: // [] -} - -/// @notice return whether contract is paused -#define macro PAUSABLE_IS_PAUSED() = takes (0) returns (0) { - 0x01 // [1] - [PAUSED_SLOT] sload // [isPaused, 1] - sub // [bool] - 0x00 mstore // [] - 0x20 0x00 return // [] -} - -/// @notice Pause the contract -#define macro PAUSABLE_PAUSE() = takes (0) returns (0) { - WHEN_NOT_PAUSED_MODIFIER() // [] - - //emit Paused(address) - caller __EVENT_HASH(Paused) 0x00 dup1 // [0, 0, EVENT_PAUSED, msg.sender] - log2 // [] - - [PAUSED] [PAUSED_SLOT] sstore // [] - stop -} - -/// @notice Unpause the contract -#define macro PAUSABLE_UNPAUSE() = takes (0) returns (0) { - WHEN_PAUSED_MODIFIER() // [] - - //emit Unpaused(address) - caller __EVENT_HASH(Unpaused) 0x00 dup1 // [0, 0, EVENT_UNPAUSED, msg.sender] - log2 // [] - - [NOT_PAUSED] [PAUSED_SLOT] sstore // [] - stop -} diff --git a/src/utils/__TEMP__xmsfvcgannmmwswbxlbvrttkmvnfxjsyErrors.huff b/src/utils/__TEMP__xmsfvcgannmmwswbxlbvrttkmvnfxjsyErrors.huff deleted file mode 100644 index e04e8e5b..00000000 --- a/src/utils/__TEMP__xmsfvcgannmmwswbxlbvrttkmvnfxjsyErrors.huff +++ /dev/null @@ -1,303 +0,0 @@ -#define function simulateRequire() pure returns () -#define function simulateAssert() pure returns () -#define function simulateAssertEq() pure returns () -#define function simulateAssertNotEq() pure returns () -#define function simulateAssertMemEq() pure returns () -#define function simulateAssertMemNotEq() pure returns () -#define function simulateAssertStorageEq() nonpayable returns () -#define function simulateAssertStorageNotEq() nonpayable returns () -#define function simulateCompilerPanic() pure returns () -#define function simulateArithmeticOverflow() pure returns () -#define function simulateDivideByZero() pure returns () -#define function simulateInvalidEnumValue() pure returns () -#define function simulateInvalidStorageByteArray() pure returns () -#define function simulateEmptyArrayPop() pure returns () -#define function simulateArrayOutOfBounds() pure returns () -#define function simulateMemoryTooLarge() pure returns () -#define function simulateUninitializedFunctionPointer() pure returns () -#define function simulateBubbleUpIfFailed(address) view returns () - -#define constant REQUIRE_LENGTH = 0x06 -#define constant REQUIRE_STRING = 0x7265766572740000000000000000000000000000000000000000000000000000 - -#define macro MAIN() = takes (0) returns (0) { - pc calldataload 0xe0 shr - dup1 __FUNC_SIG(simulateRequire) eq simulate_require jumpi - dup1 __FUNC_SIG(simulateAssert) eq simulate_assert jumpi - dup1 __FUNC_SIG(simulateAssertEq) eq simulate_assert_eq jumpi - dup1 __FUNC_SIG(simulateAssertNotEq) eq simulate_assert_not_eq jumpi - dup1 __FUNC_SIG(simulateAssertMemEq) eq simulate_assert_mem_eq jumpi - dup1 __FUNC_SIG(simulateAssertMemNotEq) eq simulate_assert_mem_not_eq jumpi - dup1 __FUNC_SIG(simulateAssertStorageEq) eq simulate_assert_storage_eq jumpi - dup1 __FUNC_SIG(simulateAssertStorageNotEq) eq simulate_assert_storage_not_eq jumpi - dup1 __FUNC_SIG(simulateCompilerPanic) eq simulate_compiler_panic jumpi - dup1 __FUNC_SIG(simulateArithmeticOverflow) eq simulateArithmeticOverflow jumpi - dup1 __FUNC_SIG(simulateDivideByZero) eq simulateDivideByZero jumpi - dup1 __FUNC_SIG(simulateInvalidEnumValue) eq simulateInvalidEnumValue jumpi - dup1 __FUNC_SIG(simulateInvalidStorageByteArray) eq simulateInvalidStorageByteArray jumpi - dup1 __FUNC_SIG(simulateEmptyArrayPop) eq simulateEmptyArrayPop jumpi - dup1 __FUNC_SIG(simulateArrayOutOfBounds) eq simulateArrayOutOfBounds jumpi - dup1 __FUNC_SIG(simulateMemoryTooLarge) eq simulateMemoryTooLarge jumpi - dup1 __FUNC_SIG(simulateUninitializedFunctionPointer) eq simulateUninitializedFunctionPointer jumpi - dup1 __FUNC_SIG(simulateBubbleUpIfFailed) eq simulateBubbleUpIfFailed jumpi - - 0x00 0x00 revert - - simulate_require: - [REQUIRE_STRING] // [message] - [REQUIRE_LENGTH] // [message_length, message] - 0x00 // [false, message_length, message] - REQUIRE() // [] - - simulate_assert: - 0x00 // [false] - ASSERT() // [] - - simulate_assert_eq: - 0x01 0x00 // [0x00, 0x01] - ASSERT_EQ() - - simulate_assert_not_eq: - 0x00 0x00 // [0x00, 0x00] - ASSERT_NOT_EQ() - - simulate_assert_mem_eq: - 0x00 dup1 mstore - 0x01 0x20 mstore - ASSERT_MEM_EQ(0x00, 0x20) - - simulate_assert_mem_not_eq: - 0x00 dup1 mstore - 0x00 0x20 mstore - ASSERT_MEM_NOT_EQ(0x00, 0x20) - - simulate_assert_storage_eq: - 0x00 dup1 sstore - 0x01 dup1 sstore - ASSERT_STORAGE_EQ(0x00, 0x01) - - simulate_assert_storage_not_eq: - 0x00 dup1 sstore - 0x00 0x01 sstore - ASSERT_STORAGE_NOT_EQ(0x00, 0x01) - - simulate_compiler_panic: - [COMPILER_PANIC] - do_panic - jump - - simulateArithmeticOverflow: - [ARITHMETIC_OVERFLOW] - do_panic - jump - - simulateDivideByZero: - [DIVIDE_BY_ZERO] - do_panic - jump - - simulateInvalidEnumValue: - [INVALID_ENUM_VALUE] - do_panic - jump - - simulateInvalidStorageByteArray: - [INVALID_STORAGE_BYTE_ARRAY] - do_panic - jump - - simulateEmptyArrayPop: - [EMPTY_ARRAY_POP] - do_panic - jump - - simulateArrayOutOfBounds: - [ARRAY_OUT_OF_BOUNDS] - do_panic - jump - - simulateMemoryTooLarge: - [MEMORY_TOO_LARGE] - do_panic - jump - - simulateUninitializedFunctionPointer: - [UNINITIALIZED_FUNCTION_POINTER] - do_panic - jump - - simulateBubbleUpIfFailed: - 0x00 // [ret_size] - dup1 // [ret_offset, ret_size] - dup1 // [args_size, ret_offset, ret_size] - dup1 // [args_offset, args_size, ret_offst, ret_size] - dup1 // [value, args_offset, args_size, ret_offst, ret_size] - 0x04 // [addr_offset, value, args_offset, args_size, ret_offst, ret_size] - calldataload // [addr, value, args_offset, args_size, ret_offst, ret_size] - gas // [gas, addr, value, args_offset, args_size, ret_offst, ret_size] - call // [success] - BUBBLE_UP_IF_FAILED() // [] - - do_panic: - PANIC() -} - - -/// @title Errors -/// @notice SPDX-License-Identifier: MIT -/// @author jtriley.eth -/// @author clabby -/// @notice Custom error utilities. - -// https://docs.soliditylang.org/en/latest/control-structures.html?highlight=panic#panic-via-assert-and-error-via-require - -// Errors -#define error Error(string) -#define error Panic(uint256) - -// Constants -// Solidity Panic Codes -#define constant COMPILER_PANIC = 0x00 -#define constant ASSERT_FALSE = 0x01 -#define constant ARITHMETIC_OVERFLOW = 0x11 -#define constant DIVIDE_BY_ZERO = 0x12 -#define constant INVALID_ENUM_VALUE = 0x21 -#define constant INVALID_STORAGE_BYTE_ARRAY = 0x22 -#define constant EMPTY_ARRAY_POP = 0x31 -#define constant ARRAY_OUT_OF_BOUNDS = 0x32 -#define constant MEMORY_TOO_LARGE = 0x41 -#define constant UNINITIALIZED_FUNCTION_POINTER = 0x51 - -/* - -Solidity Require. Error `string` MUST be no greater than 32 bytes. - -MEMORY LAYOUT WHEN THROWN -| sig || message offset || message length || message "revert" | -0x08c379a 0000000000000000000000000000000000000000000000000000000000000020 0000000000000000000000000000000000000000000000000000000000000006 7265766572740000000000000000000000000000000000000000000000000000 - -*/ -#define macro REQUIRE() = takes (3) returns (0) { - // takes: // [condition, message_length, message] - do_not_throw // [do_not_throw_jumpdest, condition, message_length, message] - jumpi // [message_length, message] - __ERROR(Error) // [error_sig, , message_length, message] - 0x00 // [mem_ptr, error_sig, message_length, message] - mstore // [message_length, message] - 0x20 // [message_offset, message_length, message] - 0x04 // [message_offset_ptr, message_offset, message_length, message] - mstore // [message_length, message] - 0x24 // [message_length_ptr, message_length, message] - mstore // [message] - 0x44 // [message_ptr, message] - mstore // [] - 0x80 // [size] - 0x00 // [offset, size] - revert // [] - do_not_throw: // [message_length, message] - pop // [message] - pop // [] -} - -/* - -Solidity Panic. - -MEMORY LAYOUT WHEN THROWN -| sig || panic code | -0x4e487b71 0000000000000000000000000000000000000000000000000000000000000001 - -*/ -#define macro PANIC() = takes (1) returns (0) { - // takes: // [panic_code] - __ERROR(Panic) // [panic_sig, panic_code] - 0x00 // [panic_sig_offset, panic_sig, panic_code] - mstore // [panic_code] - 0x04 // [panic_code_offset, panic_code] - mstore // [] - 0x24 // [revert_size] - 0x00 // [revert_offset, revert_size] - revert // [] -} - -/* -Solidity Assert. - -MEMORY LAYOUT WHEN THROWN -| sig || assert failed panic code | -0x4e487b71 0000000000000000000000000000000000000000000000000000000000000001 - -*/ -#define macro ASSERT() = takes (1) returns (0) { - // takes: // [condition] - do_not_panic // [do_not_panic_jumpdest, condition] - jumpi // [] - [ASSERT_FALSE] // [assert_false] - PANIC() // [] - do_not_panic: // [] -} - -// Assert that two stack elements are equal -#define macro ASSERT_EQ() = { - // takes: [a, b] - eq // [a == b] - ASSERT() // [] -} - -// Assert that two stack elements are not equal -#define macro ASSERT_NOT_EQ() = { - // takes: [a, b] - eq iszero // [a != b] - ASSERT() // [] -} - -// Assert that two memory offsets contain equal words -#define macro ASSERT_MEM_EQ(ptr_a, ptr_b) = { - // takes: [] - mload // [b] - mload // [a, b] - eq // [a == b] - ASSERT() // [] -} - -// Assert that two memory offsets do not contain equal words -#define macro ASSERT_MEM_NOT_EQ(ptr_a, ptr_b) = { - // takes: [] - mload // [b] - mload // [a, b] - eq iszero // [a != b] - ASSERT() // [] -} - -// Assert that two storage slots contain equal words -#define macro ASSERT_STORAGE_EQ(slot_a, slot_b) = { - // takes: [] - sload // [b] - sload // [a, b] - eq // [a == b] - ASSERT() // [] -} - -// Assert that two storage slots do not contain equal words -#define macro ASSERT_STORAGE_NOT_EQ(slot_a, slot_b) = { - // takes: [] - sload // [b] - sload // [a, b] - eq iszero // [a != b] - ASSERT() // [] -} - -/* Bubbles up revert data if call failed. Call directly after `call`, `staticcall`, `delegatecall`. */ -#define macro BUBBLE_UP_IF_FAILED() = takes (1) returns (0) { - // takes: // [call_succeeded] - call_succeeded // [call_succeeded_jumpdest, call_succeeded] - jumpi // [] - returndatasize // [returndatasize] - 0x00 // [memory_offset, returndatasize] - returndatasize // [returndatasize, memory_offset, returndatasize] - dup2 // [returndata_offset, returndatasize, memory_offset, returndatasize] - dup3 // [memory_offset, returndata_offset, returndatasize, memory_offset, returndatasize] - returndatacopy // [memory_offset, returndatasize] - revert // [] - call_succeeded: -} diff --git a/src/utils/__TEMP__zzxsgvxvutylwrboumnhnihgplkcsjdrInsertionSort.huff b/src/utils/__TEMP__zzxsgvxvutylwrboumnhnihgplkcsjdrInsertionSort.huff deleted file mode 100644 index 2959ef82..00000000 --- a/src/utils/__TEMP__zzxsgvxvutylwrboumnhnihgplkcsjdrInsertionSort.huff +++ /dev/null @@ -1,100 +0,0 @@ -/// SPDX-License-Identifier: MIT - -/// @notice Insertion Sort Function -#define function insertionSort(uint256[]) nonpayable returns (uint256[]) - -/// @notice Performs insertion sort on raw calldata -#define macro INSERTION_SORT() = takes (0) returns (0) { - SORT() // [offset, arrSize] - return // [] -} - -/// @notice The contract entrypoint -#define macro MAIN() = takes(0) returns (0) { - returndatasize calldataload 0xe0 shr // [selector] - - // notice: we don't need to duplicate the selector here - // since the selector is consumed and only used once - __FUNC_SIG(insertionSort) eq jumpSort jumpi // [] - - // Reverts if selector not present. - returndatasize returndatasize revert - - jumpSort: - INSERTION_SORT() -} - - -/// @title Sort -/// @notice SPDX-License-Identifier: MIT -/// @author tanim0la -/// @notice Insertion sort implementation - -/* MACRO */ -/// @notice Returns two items `offSet` and `arrSize` -#define macro SORT() = takes (0) returns (2) { - - 0x04 calldatasize sub // [arrSize] - dup1 // [arrSize, arrSize] - 0x04 // [offset, arrSize, arrSize] - 0x40 // [mem, offset, arrSize, arrSize] - calldatacopy // [arrSize] - - 0x01 returndatasize mstore // i = 1 - 0x60 mload // [len, arrSize] - - // For loop - start: - // End if i == len - returndatasize mload // [i, len, arrSize] - dup2 dup2 // [i, len, i, len, arrSize] - eq end jumpi - - // Assign i to j - 0x20 mstore // [len, arrSize] - - // While loop - while: - returndatasize // [0, len, arrSize] - 0x20 mload dup2 dup2 // [j, 0, j, 0, len, arrSize] - gt // [cndt1, j, 0, len, arrSize] - - - // 0x80 + (0x20 * j) - dup2 0x20 mul 0x80 add // [mem[arr[j]], cndt1, j, 0, len, arrSize] - - // 0x80 + (0x20 * (j - 0x01)) - 0x01 dup4 sub 0x20 mul 0x80 add // [mem[arr[j - i]], mem[arr[j]], cndt1, j, 0, len, arrSize] - dup2 // [mem[arr[j]], mem[arr[j - 1]], mem[arr[j]], cndt1, j, 0, len, arrSize] - - mload // [arr[j], mem[arr[j - 1]], mem[arr[j]], cndt1, j, 0, len, arrSize] - dup2 mload // [arr[j - 1], arr[j], mem[arr[j - 1]], mem[arr[j]], cndt1, j, 0, len, arrSize] - - gt dup4 // [cndt1, cndt2, mem[arr[j - 1]], mem[arr[j]], cndt1, j, 0, len, arrSize] - and continueWhile jumpi // [mem[arr[j - 1]], mem[arr[j]], cndt1, j, 0, len, arrSize] - - // Go to continue - pop pop pop pop pop // [len, arrSize] - - // Increment i++ - returndatasize mload 0x01 add // [i + 1, len, arrSize] - returndatasize mstore start jump // [len, arrSize] - - // While block - continueWhile: - // arr[j - 1] = arr[j] - dup1 mload dup3 mload // [arr[j], arr[j - i], mem[arr[j - 1]], mem[arr[j]], cndt1, j, 0, len, arrSize] - dup3 mstore // [arr[j - 1], mem[arr[j - 1]], mem[arr[j]], cndt1, j, 0, len, arrSize] - - // arr[j] = arr[j - 1] - dup3 mstore // [mem[arr[j - 1], mem[arr[j]], cndt1, j, 0, len, arrSize] - - pop pop pop // [j, 0, len, arrSize] - - // Decrement j-- - 0x01 dup2 sub // [j - 1 ,j, 0, len, arrSize] - 0x20 mstore pop pop // [len, arrSize] - while jump - end: - pop pop 0x40 // [offset, arrSize] -} diff --git a/test/auth/Auth.t.sol b/test/auth/Auth.t.sol index 0423a87d..9798ff64 100644 --- a/test/auth/Auth.t.sol +++ b/test/auth/Auth.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; +pragma solidity ^0.8.15; import "forge-std/Test.sol"; import "forge-std/console.sol"; diff --git a/test/auth/NonPayable.t.sol b/test/auth/NonPayable.t.sol index 687d3b68..442ca17f 100644 --- a/test/auth/NonPayable.t.sol +++ b/test/auth/NonPayable.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; +pragma solidity ^0.8.15; import "forge-std/Test.sol"; import {HuffDeployer} from "foundry-huff/HuffDeployer.sol"; diff --git a/test/auth/OnlyContract.t.sol b/test/auth/OnlyContract.t.sol index e290afd1..6bfafd93 100644 --- a/test/auth/OnlyContract.t.sol +++ b/test/auth/OnlyContract.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; +pragma solidity ^0.8.15; import {Test} from "forge-std/Test.sol"; diff --git a/test/auth/Owned.t.sol b/test/auth/Owned.t.sol index b8d9995c..421ab4ab 100644 --- a/test/auth/Owned.t.sol +++ b/test/auth/Owned.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; +pragma solidity ^0.8.15; import "forge-std/Test.sol"; import {HuffConfig} from "foundry-huff/HuffConfig.sol"; diff --git a/test/auth/RolesAuthority.t.sol b/test/auth/RolesAuthority.t.sol index ba65f450..3dbf60a8 100644 --- a/test/auth/RolesAuthority.t.sol +++ b/test/auth/RolesAuthority.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; +pragma solidity ^0.8.15; import "forge-std/Test.sol"; import { HuffDeployer } from "foundry-huff/HuffDeployer.sol"; diff --git a/test/data-structures/Arrays.t.sol b/test/data-structures/Arrays.t.sol index 215c07d0..a7206e24 100644 --- a/test/data-structures/Arrays.t.sol +++ b/test/data-structures/Arrays.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; +pragma solidity ^0.8.15; import "foundry-huff/HuffDeployer.sol"; import "forge-std/Test.sol"; diff --git a/test/data-structures/Bytes.t.sol b/test/data-structures/Bytes.t.sol index 931a3ed6..27584c08 100644 --- a/test/data-structures/Bytes.t.sol +++ b/test/data-structures/Bytes.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; +pragma solidity ^0.8.15; import "foundry-huff/HuffDeployer.sol"; import "forge-std/Test.sol"; diff --git a/test/data-structures/Hashmap.t.sol b/test/data-structures/Hashmap.t.sol index ca61bf18..e0b53377 100644 --- a/test/data-structures/Hashmap.t.sol +++ b/test/data-structures/Hashmap.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; +pragma solidity ^0.8.15; import "forge-std/Test.sol"; import {HuffConfig} from "foundry-huff/HuffConfig.sol"; diff --git a/test/factories/Factory.t.sol b/test/factories/Factory.t.sol index c16ff162..6341d520 100644 --- a/test/factories/Factory.t.sol +++ b/test/factories/Factory.t.sol @@ -1,2 +1,2 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; +pragma solidity ^0.8.15; diff --git a/test/factories/ProxyFactory.t.sol b/test/factories/ProxyFactory.t.sol index c16ff162..6341d520 100644 --- a/test/factories/ProxyFactory.t.sol +++ b/test/factories/ProxyFactory.t.sol @@ -1,2 +1,2 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; +pragma solidity ^0.8.15; diff --git a/test/math/FixedPointMath.t.sol b/test/math/FixedPointMath.t.sol index dd623230..f1d038c1 100644 --- a/test/math/FixedPointMath.t.sol +++ b/test/math/FixedPointMath.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; +pragma solidity ^0.8.15; import "foundry-huff/HuffDeployer.sol"; import "forge-std/Test.sol"; diff --git a/test/math/Math.t.sol b/test/math/Math.t.sol index a5167b23..f4634799 100644 --- a/test/math/Math.t.sol +++ b/test/math/Math.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; +pragma solidity ^0.8.15; import "forge-std/Test.sol"; import "foundry-huff/HuffDeployer.sol"; diff --git a/test/math/SafeMath.t.sol b/test/math/SafeMath.t.sol index b2b4a14c..731c59ba 100644 --- a/test/math/SafeMath.t.sol +++ b/test/math/SafeMath.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; +pragma solidity ^0.8.15; import "forge-std/Test.sol"; import "foundry-huff/HuffDeployer.sol"; diff --git a/test/math/Trigonometry.t.sol b/test/math/Trigonometry.t.sol index 7b3ba2d2..a67f22b8 100644 --- a/test/math/Trigonometry.t.sol +++ b/test/math/Trigonometry.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; +pragma solidity ^0.8.15; import "foundry-huff/HuffDeployer.sol"; import "forge-std/Test.sol"; diff --git a/test/mechanisms/huff-clones/HuffClone.t.sol b/test/mechanisms/huff-clones/HuffClone.t.sol index 73c178ea..f726dbec 100644 --- a/test/mechanisms/huff-clones/HuffClone.t.sol +++ b/test/mechanisms/huff-clones/HuffClone.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: BSD -pragma solidity ^0.8.19; +pragma solidity ^0.8.15; import {Test} from "forge-std/Test.sol"; import {HuffDeployer} from "foundry-huff/HuffDeployer.sol"; diff --git a/test/mechanisms/huff-clones/HuffCloneFactory.t.sol b/test/mechanisms/huff-clones/HuffCloneFactory.t.sol index 5600c423..af1581cb 100644 --- a/test/mechanisms/huff-clones/HuffCloneFactory.t.sol +++ b/test/mechanisms/huff-clones/HuffCloneFactory.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: BSD -pragma solidity ^0.8.19; +pragma solidity ^0.8.15; import {Test} from "forge-std/Test.sol"; import {HuffDeployer} from "foundry-huff/HuffDeployer.sol"; diff --git a/test/mechanisms/huff-clones/Interfaces.sol b/test/mechanisms/huff-clones/Interfaces.sol index 9da75578..646ee1ee 100644 --- a/test/mechanisms/huff-clones/Interfaces.sol +++ b/test/mechanisms/huff-clones/Interfaces.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: BSD -pragma solidity ^0.8.19; +pragma solidity ^0.8.15; interface IExampleClone { function param1() external pure returns (address); diff --git a/test/mechanisms/huff-vrgda/LinearVRGDA.t.sol b/test/mechanisms/huff-vrgda/LinearVRGDA.t.sol index f15424d2..eca307f9 100644 --- a/test/mechanisms/huff-vrgda/LinearVRGDA.t.sol +++ b/test/mechanisms/huff-vrgda/LinearVRGDA.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; +pragma solidity ^0.8.15; import "forge-std/Test.sol"; diff --git a/test/mechanisms/huff-vrgda/LogisticVRGDA.t.sol b/test/mechanisms/huff-vrgda/LogisticVRGDA.t.sol index 93426acd..5918e037 100644 --- a/test/mechanisms/huff-vrgda/LogisticVRGDA.t.sol +++ b/test/mechanisms/huff-vrgda/LogisticVRGDA.t.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; +pragma solidity ^0.8.15; import {DSTestPlus} from "solmate/test/utils/DSTestPlus.sol"; diff --git a/test/mechanisms/huff-vrgda/utils/SignedWadMath.sol b/test/mechanisms/huff-vrgda/utils/SignedWadMath.sol index b256a3dd..99e46512 100644 --- a/test/mechanisms/huff-vrgda/utils/SignedWadMath.sol +++ b/test/mechanisms/huff-vrgda/utils/SignedWadMath.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; +pragma solidity ^0.8.15; /// @title Signed Wad Math /// @author transmissions11 diff --git a/test/proxies/Clones.t.sol b/test/proxies/Clones.t.sol index ae35ab1f..a40153df 100644 --- a/test/proxies/Clones.t.sol +++ b/test/proxies/Clones.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.19; +pragma solidity 0.8.15; import "foundry-huff/HuffDeployer.sol"; diff --git a/test/proxies/ERC1967Proxy.t.sol b/test/proxies/ERC1967Proxy.t.sol index 114f8dd6..c0bdf468 100644 --- a/test/proxies/ERC1967Proxy.t.sol +++ b/test/proxies/ERC1967Proxy.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.19; +pragma solidity 0.8.15; import "foundry-huff/HuffDeployer.sol"; import "forge-std/Test.sol"; diff --git a/test/proxies/mocks/MockBeacon.sol b/test/proxies/mocks/MockBeacon.sol index 5af41004..97969c1a 100644 --- a/test/proxies/mocks/MockBeacon.sol +++ b/test/proxies/mocks/MockBeacon.sol @@ -1,5 +1,5 @@ -pragma solidity 0.8.19; +pragma solidity 0.8.15; /** * @dev This is the interface that {BeaconProxy} expects of its beacon. diff --git a/test/proxies/mocks/MockProxiableUUID.sol b/test/proxies/mocks/MockProxiableUUID.sol index e74fbfd8..e73fdee6 100644 --- a/test/proxies/mocks/MockProxiableUUID.sol +++ b/test/proxies/mocks/MockProxiableUUID.sol @@ -1,4 +1,4 @@ -pragma solidity 0.8.19; +pragma solidity 0.8.15; import { MockERC1155 } from "solmate/test/utils/mocks/MockERC1155.sol"; diff --git a/test/proxies/mocks/MockReturner.sol b/test/proxies/mocks/MockReturner.sol index 3e393820..8a354a17 100644 --- a/test/proxies/mocks/MockReturner.sol +++ b/test/proxies/mocks/MockReturner.sol @@ -1,4 +1,4 @@ -pragma solidity 0.8.19; +pragma solidity 0.8.15; /// @dev Used to test proxies that they can both receive and return data contract MockReturner { diff --git a/test/proxies/mocks/NotUUPSMockProxiableUUID.sol b/test/proxies/mocks/NotUUPSMockProxiableUUID.sol index 9465246a..a227d5f3 100644 --- a/test/proxies/mocks/NotUUPSMockProxiableUUID.sol +++ b/test/proxies/mocks/NotUUPSMockProxiableUUID.sol @@ -1,4 +1,4 @@ -pragma solidity 0.8.19; +pragma solidity 0.8.15; import { MockERC1155 } from "solmate/test/utils/mocks/MockERC1155.sol"; diff --git a/test/test-utils/FuzzingUtils.sol b/test/test-utils/FuzzingUtils.sol index 3f65ec2b..1a2fb488 100644 --- a/test/test-utils/FuzzingUtils.sol +++ b/test/test-utils/FuzzingUtils.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; +pragma solidity ^0.8.15; // adapter from: https://github.com/transmissions11/solmate/blob/main/src/test/utils/DSTestPlus.sol abstract contract FuzzingUtils { diff --git a/test/test-utils/NonMatchingSelectorHelper.sol b/test/test-utils/NonMatchingSelectorHelper.sol index 2875f14b..ec00f67a 100644 --- a/test/test-utils/NonMatchingSelectorHelper.sol +++ b/test/test-utils/NonMatchingSelectorHelper.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; +pragma solidity ^0.8.15; import "forge-std/Test.sol"; diff --git a/test/tokens/ERC1155.t.sol b/test/tokens/ERC1155.t.sol index 6f8d2176..664245dc 100644 --- a/test/tokens/ERC1155.t.sol +++ b/test/tokens/ERC1155.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; +pragma solidity ^0.8.15; import "foundry-huff/HuffDeployer.sol"; import "forge-std/Test.sol"; diff --git a/test/tokens/ERC20.t.sol b/test/tokens/ERC20.t.sol index 7e40ec6a..eae507df 100644 --- a/test/tokens/ERC20.t.sol +++ b/test/tokens/ERC20.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; +pragma solidity ^0.8.15; import "foundry-huff/HuffDeployer.sol"; import "forge-std/Test.sol"; diff --git a/test/tokens/ERC4626.t.sol b/test/tokens/ERC4626.t.sol index 50edc05d..7a9fab1d 100644 --- a/test/tokens/ERC4626.t.sol +++ b/test/tokens/ERC4626.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; +pragma solidity ^0.8.15; import "forge-std/Test.sol"; import "foundry-huff/HuffDeployer.sol"; diff --git a/test/tokens/ERC721.t.sol b/test/tokens/ERC721.t.sol index b7a1ad81..d8686529 100644 --- a/test/tokens/ERC721.t.sol +++ b/test/tokens/ERC721.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; +pragma solidity ^0.8.15; import "forge-std/Test.sol"; import "foundry-huff/HuffDeployer.sol"; diff --git a/test/utils/BitPackLib.t.sol b/test/utils/BitPackLib.t.sol index 7af81e44..990dc8fa 100644 --- a/test/utils/BitPackLib.t.sol +++ b/test/utils/BitPackLib.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; +pragma solidity ^0.8.15; import "forge-std/Test.sol"; import "foundry-huff/HuffDeployer.sol"; diff --git a/test/utils/CREATE3.t.sol b/test/utils/CREATE3.t.sol index f100e92d..962e58b1 100644 --- a/test/utils/CREATE3.t.sol +++ b/test/utils/CREATE3.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; +pragma solidity ^0.8.15; import "foundry-huff/HuffDeployer.sol"; import "forge-std/Test.sol"; diff --git a/test/utils/Calls.t.sol b/test/utils/Calls.t.sol index dd9762ec..b97ba19f 100644 --- a/test/utils/Calls.t.sol +++ b/test/utils/Calls.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; +pragma solidity ^0.8.15; import "forge-std/Test.sol"; import "foundry-huff/HuffDeployer.sol"; diff --git a/test/utils/Constants.t.sol b/test/utils/Constants.t.sol index d1cc796d..aa5de68f 100644 --- a/test/utils/Constants.t.sol +++ b/test/utils/Constants.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; +pragma solidity ^0.8.15; import "forge-std/Test.sol"; import "foundry-huff/HuffDeployer.sol"; diff --git a/test/utils/DateTimeLib.t.sol b/test/utils/DateTimeLib.t.sol index 1a581a67..254057d4 100644 --- a/test/utils/DateTimeLib.t.sol +++ b/test/utils/DateTimeLib.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: Unlicense -pragma solidity ^0.8.19; +pragma solidity ^0.8.15; import "foundry-huff/HuffDeployer.sol"; import "forge-std/console.sol"; diff --git a/test/utils/ECDSA.t.sol b/test/utils/ECDSA.t.sol index d14776c2..7a9891d3 100644 --- a/test/utils/ECDSA.t.sol +++ b/test/utils/ECDSA.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; +pragma solidity ^0.8.15; import "forge-std/Test.sol"; import "foundry-huff/HuffDeployer.sol"; diff --git a/test/utils/Errors.t.sol b/test/utils/Errors.t.sol index fbaa66f0..a87311a8 100644 --- a/test/utils/Errors.t.sol +++ b/test/utils/Errors.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; +pragma solidity ^0.8.15; import "foundry-huff/HuffDeployer.sol"; import "forge-std/Test.sol"; diff --git a/test/utils/Ethers.t.sol b/test/utils/Ethers.t.sol index 1ab7112d..8c7a7a6d 100644 --- a/test/utils/Ethers.t.sol +++ b/test/utils/Ethers.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; +pragma solidity ^0.8.15; import "forge-std/Test.sol"; import "foundry-huff/HuffDeployer.sol"; diff --git a/test/utils/InsertionSort.t.sol b/test/utils/InsertionSort.t.sol index a1ac9782..b10edde8 100644 --- a/test/utils/InsertionSort.t.sol +++ b/test/utils/InsertionSort.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; +pragma solidity ^0.8.15; import "foundry-huff/HuffDeployer.sol"; import "forge-std/Test.sol"; diff --git a/test/utils/JumpTableUtil.t.sol b/test/utils/JumpTableUtil.t.sol index dae5fd7c..fdaee655 100644 --- a/test/utils/JumpTableUtil.t.sol +++ b/test/utils/JumpTableUtil.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; +pragma solidity ^0.8.15; import "foundry-huff/HuffDeployer.sol"; import "forge-std/Test.sol"; diff --git a/test/utils/LibBit.t.sol b/test/utils/LibBit.t.sol index e84e2b73..cf6a235a 100644 --- a/test/utils/LibBit.t.sol +++ b/test/utils/LibBit.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; +pragma solidity ^0.8.15; import "foundry-huff/HuffDeployer.sol"; import "forge-std/Test.sol"; diff --git a/test/utils/MerkleDistributor.t.sol b/test/utils/MerkleDistributor.t.sol index 080b9e34..374438ec 100644 --- a/test/utils/MerkleDistributor.t.sol +++ b/test/utils/MerkleDistributor.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; +pragma solidity ^0.8.15; import "foundry-huff/HuffDeployer.sol"; import "forge-std/Test.sol"; diff --git a/test/utils/MerkleProofLib.t.sol b/test/utils/MerkleProofLib.t.sol index 4aa72e42..e2bf1355 100644 --- a/test/utils/MerkleProofLib.t.sol +++ b/test/utils/MerkleProofLib.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; +pragma solidity ^0.8.15; import "foundry-huff/HuffDeployer.sol"; import "forge-std/Test.sol"; diff --git a/test/utils/Multicallable.t.sol b/test/utils/Multicallable.t.sol index cac819b6..10e2e869 100644 --- a/test/utils/Multicallable.t.sol +++ b/test/utils/Multicallable.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; +pragma solidity ^0.8.15; import "foundry-huff/HuffDeployer.sol"; import "forge-std/Test.sol"; diff --git a/test/utils/Pausable.t.sol b/test/utils/Pausable.t.sol index f2282819..66e80e9f 100644 --- a/test/utils/Pausable.t.sol +++ b/test/utils/Pausable.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; +pragma solidity ^0.8.15; import "foundry-huff/HuffDeployer.sol"; import "forge-std/Test.sol"; diff --git a/test/utils/ReentrancyGuard.t.sol b/test/utils/ReentrancyGuard.t.sol index 85a0ff4b..e5ca2641 100644 --- a/test/utils/ReentrancyGuard.t.sol +++ b/test/utils/ReentrancyGuard.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; +pragma solidity ^0.8.15; import "foundry-huff/HuffDeployer.sol"; import "forge-std/Test.sol"; diff --git a/test/utils/Refunded.t.sol b/test/utils/Refunded.t.sol index 48bded83..76a4074a 100644 --- a/test/utils/Refunded.t.sol +++ b/test/utils/Refunded.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; +pragma solidity ^0.8.15; import "foundry-huff/HuffDeployer.sol"; import "forge-std/Test.sol"; diff --git a/test/utils/SSTORE2.t.sol b/test/utils/SSTORE2.t.sol index b189246d..cc593a71 100644 --- a/test/utils/SSTORE2.t.sol +++ b/test/utils/SSTORE2.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; +pragma solidity ^0.8.15; import "foundry-huff/HuffDeployer.sol"; import "forge-std/Test.sol"; diff --git a/test/utils/SafeTransferLib.t.sol b/test/utils/SafeTransferLib.t.sol index 07ce57f9..b83c2a1f 100644 --- a/test/utils/SafeTransferLib.t.sol +++ b/test/utils/SafeTransferLib.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.19; +pragma solidity 0.8.15; import {MockERC20} from "./safe-transfer-lib-mocks/mocks/MockERC20.sol"; import {RevertingToken} from "./safe-transfer-lib-mocks/weird-tokens/RevertingToken.sol"; diff --git a/test/utils/Shuffling.t.sol b/test/utils/Shuffling.t.sol index 425ddbd8..d9dea688 100644 --- a/test/utils/Shuffling.t.sol +++ b/test/utils/Shuffling.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; +pragma solidity ^0.8.15; import { Test } from "forge-std/Test.sol"; import { console2 } from "forge-std/console2.sol"; diff --git a/test/utils/TSOwnable.t.sol b/test/utils/TSOwnable.t.sol index 119cc34b..7849e1c6 100644 --- a/test/utils/TSOwnable.t.sol +++ b/test/utils/TSOwnable.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; +pragma solidity ^0.8.15; import "foundry-huff/HuffConfig.sol"; import "forge-std/Test.sol"; diff --git a/test/utils/safe-transfer-lib-mocks/mocks/MockERC20.sol b/test/utils/safe-transfer-lib-mocks/mocks/MockERC20.sol index 846ba347..3adb1f5c 100644 --- a/test/utils/safe-transfer-lib-mocks/mocks/MockERC20.sol +++ b/test/utils/safe-transfer-lib-mocks/mocks/MockERC20.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; +pragma solidity ^0.8.15; import {ERC20} from "solmate/tokens/ERC20.sol"; diff --git a/test/utils/safe-transfer-lib-mocks/weird-tokens/MissingReturnToken.sol b/test/utils/safe-transfer-lib-mocks/weird-tokens/MissingReturnToken.sol index 6e276b7b..5e94a0e0 100644 --- a/test/utils/safe-transfer-lib-mocks/weird-tokens/MissingReturnToken.sol +++ b/test/utils/safe-transfer-lib-mocks/weird-tokens/MissingReturnToken.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; +pragma solidity ^0.8.15; contract MissingReturnToken { /*/////////////////////////////////////////////////////////////// diff --git a/test/utils/safe-transfer-lib-mocks/weird-tokens/ReturnsFalseToken.sol b/test/utils/safe-transfer-lib-mocks/weird-tokens/ReturnsFalseToken.sol index c29416bb..c0137e12 100644 --- a/test/utils/safe-transfer-lib-mocks/weird-tokens/ReturnsFalseToken.sol +++ b/test/utils/safe-transfer-lib-mocks/weird-tokens/ReturnsFalseToken.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; +pragma solidity ^0.8.15; contract ReturnsFalseToken { /*/////////////////////////////////////////////////////////////// diff --git a/test/utils/safe-transfer-lib-mocks/weird-tokens/ReturnsGarbageToken.sol b/test/utils/safe-transfer-lib-mocks/weird-tokens/ReturnsGarbageToken.sol index b53ad856..3edcb167 100644 --- a/test/utils/safe-transfer-lib-mocks/weird-tokens/ReturnsGarbageToken.sol +++ b/test/utils/safe-transfer-lib-mocks/weird-tokens/ReturnsGarbageToken.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; +pragma solidity ^0.8.15; contract ReturnsGarbageToken { /*/////////////////////////////////////////////////////////////// diff --git a/test/utils/safe-transfer-lib-mocks/weird-tokens/ReturnsTooLittleToken.sol b/test/utils/safe-transfer-lib-mocks/weird-tokens/ReturnsTooLittleToken.sol index 8d8690b9..03b997c7 100644 --- a/test/utils/safe-transfer-lib-mocks/weird-tokens/ReturnsTooLittleToken.sol +++ b/test/utils/safe-transfer-lib-mocks/weird-tokens/ReturnsTooLittleToken.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; +pragma solidity ^0.8.15; contract ReturnsTooLittleToken { /*/////////////////////////////////////////////////////////////// diff --git a/test/utils/safe-transfer-lib-mocks/weird-tokens/ReturnsTooMuchToken.sol b/test/utils/safe-transfer-lib-mocks/weird-tokens/ReturnsTooMuchToken.sol index 5ef2da9e..69774c8a 100644 --- a/test/utils/safe-transfer-lib-mocks/weird-tokens/ReturnsTooMuchToken.sol +++ b/test/utils/safe-transfer-lib-mocks/weird-tokens/ReturnsTooMuchToken.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; +pragma solidity ^0.8.15; contract ReturnsTooMuchToken { /*/////////////////////////////////////////////////////////////// diff --git a/test/utils/safe-transfer-lib-mocks/weird-tokens/ReturnsTwoToken.sol b/test/utils/safe-transfer-lib-mocks/weird-tokens/ReturnsTwoToken.sol index 3554325b..b4b7e46a 100644 --- a/test/utils/safe-transfer-lib-mocks/weird-tokens/ReturnsTwoToken.sol +++ b/test/utils/safe-transfer-lib-mocks/weird-tokens/ReturnsTwoToken.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; +pragma solidity ^0.8.15; contract ReturnsTwoToken { /*/////////////////////////////////////////////////////////////// diff --git a/test/utils/safe-transfer-lib-mocks/weird-tokens/RevertingToken.sol b/test/utils/safe-transfer-lib-mocks/weird-tokens/RevertingToken.sol index a7c9af5c..99c051eb 100644 --- a/test/utils/safe-transfer-lib-mocks/weird-tokens/RevertingToken.sol +++ b/test/utils/safe-transfer-lib-mocks/weird-tokens/RevertingToken.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; +pragma solidity ^0.8.15; contract RevertingToken { /*///////////////////////////////////////////////////////////////