EOF disables a number of opcodes. Right now, if your contract contains any of those it will get compiled but will not be deployable.
I think it's best that we make a separate repo while devving these escape hatches. Doesn't need npm.
I feel that some stuff might not be fit for automatic transpilation. We'll know it when we get there.
A lot of the code will be a one-time transpilation. There are also many devious edge cases. A hand-transpilation approach might be overall more effort efficient even in the long run. Additionally, hand-transpiling will allow us to perform EOF specific hand-optimizations if time permits.
These will be full-time efforts.
In the long term, we will need to maintain two 1:1 copies of Solady, the legacy in src and eof.
Our top priority is drop-in compatibility with EOF Solidity compiler.
We'll just go with full code-reuse style. We do NOT need inline anything.
In fact, I have a feel that contracts with more code reuse are better suited for EOF, with the subroutine stuff.
LibClone might actually have lesser SLOCs with rampant code reuse.
Going forward, Solady's legacy code will still be at the forefront of cutting edge features.
We will need to have some discipline on keeping the EOF quickly up to parity with the non-EOF code, but if resources are limited, we will just create a new backlog issue on porting it to EOF.
[
{
"srcPath": "src/Milady.sol",
"lastModifiedGitTimestamp": 1730050433
},
{
"srcPath": "src/accounts/Receiver.sol",
"lastModifiedGitTimestamp": 1725453789
},
{
"srcPath": "src/auth/Ownable.sol",
"lastModifiedGitTimestamp": 1697754631
},
{
"srcPath": "src/auth/OwnableRoles.sol",
"lastModifiedGitTimestamp": 1720385905
},
{
"srcPath": "src/tokens/ERC2981.sol",
"lastModifiedGitTimestamp": 1686120478
},
{
"srcPath": "src/tokens/ERC6909.sol",
"lastModifiedGitTimestamp": 1703921789
},
{
"srcPath": "src/utils/Base64.sol",
"lastModifiedGitTimestamp": 1709232746
},
{
"srcPath": "src/utils/DateTimeLib.sol",
"lastModifiedGitTimestamp": 1705005025
},
{
"srcPath": "src/utils/DynamicBufferLib.sol",
"lastModifiedGitTimestamp": 1726471158
},
{
"srcPath": "src/utils/EIP712.sol",
"lastModifiedGitTimestamp": 1698938547
},
{
"srcPath": "src/utils/ERC1967FactoryConstants.sol",
"lastModifiedGitTimestamp": 1720878475
},
{
"srcPath": "src/utils/EfficientHashLib.sol",
"lastModifiedGitTimestamp": 1724696571
},
{
"srcPath": "src/utils/EnumerableSetLib.sol",
"lastModifiedGitTimestamp": 1728734415
},
{
"srcPath": "src/utils/FixedPointMathLib.sol",
"lastModifiedGitTimestamp": 1725075080
},
{
"srcPath": "src/utils/JSONParserLib.sol",
"lastModifiedGitTimestamp": 1705066803
},
{
"srcPath": "src/utils/LibBit.sol",
"lastModifiedGitTimestamp": 1717740645
},
{
"srcPath": "src/utils/LibBitmap.sol",
"lastModifiedGitTimestamp": 1721699660
},
{
"srcPath": "src/utils/LibBytes.sol",
"lastModifiedGitTimestamp": 1730857419
},
{
"srcPath": "src/utils/LibMap.sol",
"lastModifiedGitTimestamp": 1690778106
},
{
"srcPath": "src/utils/LibPRNG.sol",
"lastModifiedGitTimestamp": 1719111683
},
{
"srcPath": "src/utils/LibRLP.sol",
"lastModifiedGitTimestamp": 1726471715
},
{
"srcPath": "src/utils/LibSort.sol",
"lastModifiedGitTimestamp": 1727873015
},
{
"srcPath": "src/utils/LibString.sol",
"lastModifiedGitTimestamp": 1730857419
},
{
"srcPath": "src/utils/LibTransient.sol",
"lastModifiedGitTimestamp": 1730765339
},
{
"srcPath": "src/utils/MerkleProofLib.sol",
"lastModifiedGitTimestamp": 1697511114
},
{
"srcPath": "src/utils/MinHeapLib.sol",
"lastModifiedGitTimestamp": 1723492714
},
{
"srcPath": "src/utils/ReentrancyGuardTransient.sol",
"lastModifiedGitTimestamp": 1730497227
},
{
"srcPath": "src/utils/SafeCastLib.sol",
"lastModifiedGitTimestamp": 1715433563
},
{
"srcPath": "src/utils/Initializable.sol",
"scores": {
"extcodesize": 1
},
"lastModifiedGitTimestamp": 1705139261
},
{
"srcPath": "src/utils/RedBlackTreeLib.sol",
"scores": {
"codesize": 1
},
"lastModifiedGitTimestamp": 1717740645
},
{
"srcPath": "src/utils/ReentrancyGuard.sol",
"scores": {
"codesize": 1
},
"lastModifiedGitTimestamp": 1706263836
},
{
"srcPath": "src/tokens/ERC20.sol",
"scores": {
"staticcall": 1
},
"lastModifiedGitTimestamp": 1729135343
},
{
"srcPath": "src/tokens/ERC20Votes.sol",
"scores": {
"staticcall": 1
},
"lastModifiedGitTimestamp": 1729135343
},
{
"srcPath": "src/tokens/ERC4626.sol",
"scores": {
"staticcall": 1
},
"lastModifiedGitTimestamp": 1717740645
},
{
"srcPath": "src/utils/MetadataReaderLib.sol",
"scores": {
"staticcall": 2
},
"lastModifiedGitTimestamp": 1723462389
},
{
"srcPath": "src/accounts/ERC4337Factory.sol",
"scores": {
"codesize": 1,
"call": 1
},
"lastModifiedGitTimestamp": 1703276182
},
{
"srcPath": "src/accounts/ERC6551Proxy.sol",
"scores": {
"codesize": 1,
"delegatecall": 1
},
"lastModifiedGitTimestamp": 1710219546
},
{
"srcPath": "src/utils/Multicallable.sol",
"scores": {
"codesize": 1,
"delegatecall": 1
},
"lastModifiedGitTimestamp": 1725108562
},
{
"srcPath": "src/utils/UpgradeableBeacon.sol",
"scores": {
"codesize": 2,
"extcodesize": 1
},
"lastModifiedGitTimestamp": 1715045031
},
{
"srcPath": "src/auth/EnumerableRoles.sol",
"scores": {
"staticcall": 2
},
"lastModifiedGitTimestamp": 1728811386
},
{
"srcPath": "src/tokens/WETH.sol",
"scores": {
"codesize": 2,
"call": 1
},
"lastModifiedGitTimestamp": 1719095021
},
{
"srcPath": "src/utils/CREATE3.sol",
"scores": {
"extcodesize": 1,
"create2": 1,
"call": 1
},
"lastModifiedGitTimestamp": 1720878475
},
{
"srcPath": "src/utils/DynamicArrayLib.sol",
"scores": {
"codesize": 2,
"codecopy": 2
},
"lastModifiedGitTimestamp": 1728355500
},
{
"srcPath": "src/utils/GasBurnerLib.sol",
"scores": {
"codecopy": 2,
"staticcall": 1
},
"lastModifiedGitTimestamp": 1721303834
},
{
"srcPath": "src/utils/WebAuthn.sol",
"scores": {
"staticcall": 2
},
"lastModifiedGitTimestamp": 1730239265
},
{
"srcPath": "src/accounts/Pod.sol",
"scores": {
"codesize": 2,
"call": 2
},
"lastModifiedGitTimestamp": 1727862888
},
{
"srcPath": "src/utils/DeploylessPredeployQueryer.sol",
"scores": {
"codesize": 1,
"extcodesize": 1,
"call": 2
},
"lastModifiedGitTimestamp": 1713208829
},
{
"srcPath": "src/utils/ERC1967Factory.sol",
"scores": {
"create": 1,
"create2": 1,
"call": 2
},
"lastModifiedGitTimestamp": 1706770409
},
{
"srcPath": "src/utils/UUPSUpgradeable.sol",
"scores": {
"codesize": 2,
"staticcall": 1,
"delegatecall": 1
},
"lastModifiedGitTimestamp": 1715045031
},
{
"srcPath": "src/utils/P256.sol",
"scores": {
"staticcall": 4
},
"lastModifiedGitTimestamp": 1723742125
},
{
"srcPath": "src/utils/LibZip.sol",
"scores": {
"codesize": 4,
"codecopy": 3,
"delegatecall": 1
},
"lastModifiedGitTimestamp": 1707000199
},
{
"srcPath": "src/accounts/LibERC6551.sol",
"scores": {
"extcodesize": 2,
"extcodecopy": 7,
"call": 1
},
"lastModifiedGitTimestamp": 1709789868
},
{
"srcPath": "src/tokens/ERC721.sol",
"scores": {
"codesize": 6,
"extcodesize": 1,
"call": 1,
"staticcall": 1
},
"lastModifiedGitTimestamp": 1711338124
},
{
"srcPath": "src/utils/SSTORE2.sol",
"scores": {
"codesize": 1,
"extcodesize": 4,
"extcodecopy": 3,
"create": 1,
"create2": 2,
"call": 1
},
"lastModifiedGitTimestamp": 1728067022
},
{
"srcPath": "src/accounts/ERC1271.sol",
"scores": {
"codesize": 1,
"gaslimit": 2,
"gasprice": 8,
"staticcall": 2
},
"lastModifiedGitTimestamp": 1730050055
},
{
"srcPath": "src/accounts/ERC6551.sol",
"scores": {
"codesize": 2,
"extcodecopy": 3,
"call": 2,
"staticcall": 3
},
"lastModifiedGitTimestamp": 1717372305
},
{
"srcPath": "src/utils/ECDSA.sol",
"scores": {
"staticcall": 8
},
"lastModifiedGitTimestamp": 1730845513
},
{
"srcPath": "src/utils/Lifebuoy.sol",
"scores": {
"codesize": 4,
"extcodesize": 3,
"call": 5,
"staticcall": 1
},
"lastModifiedGitTimestamp": 1724378720
},
{
"srcPath": "src/accounts/ERC4337.sol",
"scores": {
"codesize": 11,
"extcodesize": 2,
"call": 5,
"staticcall": 1,
"delegatecall": 1
},
"lastModifiedGitTimestamp": 1713297028
},
{
"srcPath": "src/tokens/ERC1155.sol",
"scores": {
"extcodesize": 3,
"call": 4,
"staticcall": 10
},
"lastModifiedGitTimestamp": 1718114922
},
{
"srcPath": "src/utils/ext/delegatexyz/DelegateCheckerLib.sol",
"scores": {
"staticcall": 20
},
"lastModifiedGitTimestamp": 1720170364
},
{
"srcPath": "src/utils/SignatureCheckerLib.sol",
"scores": {
"codesize": 2,
"extcodesize": 2,
"call": 3,
"staticcall": 21
},
"lastModifiedGitTimestamp": 1730845513
},
{
"srcPath": "src/utils/SafeTransferLib.sol",
"scores": {
"codesize": 29,
"extcodesize": 11,
"create": 4,
"call": 21,
"staticcall": 6
},
"lastModifiedGitTimestamp": 1729206025
},
{
"srcPath": "src/utils/LibClone.sol",
"scores": {
"codesize": 23,
"codecopy": 3,
"extcodesize": 25,
"extcodecopy": 16,
"create": 11,
"create2": 21,
"call": 11,
"staticcall": 16
},
"lastModifiedGitTimestamp": 1730767406
}
]
https://github.com/ithacaxyz/odyssey-examples/tree/main/chapter1/eof
Primer
EOF disables a number of opcodes. Right now, if your contract contains any of those it will get compiled but will not be deployable.
The banned opcodes are:
CODESIZE,CODECOPY,EXTCODESIZE,EXTCODECOPY,EXTCODEHASH.JUMP,JUMPI,PC.GAS,GASLIMIT,GASPRICE.CREATE,CALL,DELEGATECALL,CREATE2,STATICCALL.SELFDESTRUCT,CALLCODE.Plan
Test with
forge test --eof.Tests
test__codesize()to be removed. We cannot usecodesizeanymore. Not really a dealbreaker._brutalizeMemory(). We will simply have to spamkeccak256andmcopy.Transpiling
Escape hatch
https://github.com/Vectorized/escape-hatch
To be deployed via Nick's factory:
EXTCODECOPY,EXTCODESIZECREATECREATE2SELFDESTRUCTto force send EtherGas limited
CALLGas limited
STATICCALLI think it's best that we make a separate repo while devving these escape hatches. Doesn't need npm.
Notes
All addresses passed in to
EXTCALL,EXTDELEGATECALL,EXTDELEGATECALLmust have upper 96 bits cleaned. Also, their behavior are different.Hand translation might not be that hard. We can use functions to encapsulate if it looks better.
Transpilation
We might define an
eof/srcandeof/testdirectory. These directories are intentionally not insrcortest, so that when people install Solady for use in a regular Solidity project, they still can compile hassle free.I'm thinking if it might be better if we keep the EOF stuff in Solady:
tstorelibs on a non EOF project (which we expect most users to), they might run into compilation hassles.I feel that some stuff might not be fit for automatic transpilation. We'll know it when we get there.
A lot of the code will be a one-time transpilation. There are also many devious edge cases. A hand-transpilation approach might be overall more effort efficient even in the long run. Additionally, hand-transpiling will allow us to perform EOF specific hand-optimizations if time permits.
Effort estimates
TestPlus.sol,Brutalizer.sol,SoladyTest.sol,Test.sol.These will be full-time efforts.
In the long term, we will need to maintain two 1:1 copies of Solady, the legacy in
srcandeof.Priorities
Our top priority is drop-in compatibility with EOF Solidity compiler.
We'll just go with full code-reuse style. We do NOT need inline anything.
In fact, I have a feel that contracts with more code reuse are better suited for EOF, with the subroutine stuff.
LibClone might actually have lesser SLOCs with rampant code reuse.
Regression
Going forward, Solady's legacy code will still be at the forefront of cutting edge features.
We will need to have some discipline on keeping the EOF quickly up to parity with the non-EOF code, but if resources are limited, we will just create a new backlog issue on porting it to EOF.
File analysis
[ { "srcPath": "src/Milady.sol", "lastModifiedGitTimestamp": 1730050433 }, { "srcPath": "src/accounts/Receiver.sol", "lastModifiedGitTimestamp": 1725453789 }, { "srcPath": "src/auth/Ownable.sol", "lastModifiedGitTimestamp": 1697754631 }, { "srcPath": "src/auth/OwnableRoles.sol", "lastModifiedGitTimestamp": 1720385905 }, { "srcPath": "src/tokens/ERC2981.sol", "lastModifiedGitTimestamp": 1686120478 }, { "srcPath": "src/tokens/ERC6909.sol", "lastModifiedGitTimestamp": 1703921789 }, { "srcPath": "src/utils/Base64.sol", "lastModifiedGitTimestamp": 1709232746 }, { "srcPath": "src/utils/DateTimeLib.sol", "lastModifiedGitTimestamp": 1705005025 }, { "srcPath": "src/utils/DynamicBufferLib.sol", "lastModifiedGitTimestamp": 1726471158 }, { "srcPath": "src/utils/EIP712.sol", "lastModifiedGitTimestamp": 1698938547 }, { "srcPath": "src/utils/ERC1967FactoryConstants.sol", "lastModifiedGitTimestamp": 1720878475 }, { "srcPath": "src/utils/EfficientHashLib.sol", "lastModifiedGitTimestamp": 1724696571 }, { "srcPath": "src/utils/EnumerableSetLib.sol", "lastModifiedGitTimestamp": 1728734415 }, { "srcPath": "src/utils/FixedPointMathLib.sol", "lastModifiedGitTimestamp": 1725075080 }, { "srcPath": "src/utils/JSONParserLib.sol", "lastModifiedGitTimestamp": 1705066803 }, { "srcPath": "src/utils/LibBit.sol", "lastModifiedGitTimestamp": 1717740645 }, { "srcPath": "src/utils/LibBitmap.sol", "lastModifiedGitTimestamp": 1721699660 }, { "srcPath": "src/utils/LibBytes.sol", "lastModifiedGitTimestamp": 1730857419 }, { "srcPath": "src/utils/LibMap.sol", "lastModifiedGitTimestamp": 1690778106 }, { "srcPath": "src/utils/LibPRNG.sol", "lastModifiedGitTimestamp": 1719111683 }, { "srcPath": "src/utils/LibRLP.sol", "lastModifiedGitTimestamp": 1726471715 }, { "srcPath": "src/utils/LibSort.sol", "lastModifiedGitTimestamp": 1727873015 }, { "srcPath": "src/utils/LibString.sol", "lastModifiedGitTimestamp": 1730857419 }, { "srcPath": "src/utils/LibTransient.sol", "lastModifiedGitTimestamp": 1730765339 }, { "srcPath": "src/utils/MerkleProofLib.sol", "lastModifiedGitTimestamp": 1697511114 }, { "srcPath": "src/utils/MinHeapLib.sol", "lastModifiedGitTimestamp": 1723492714 }, { "srcPath": "src/utils/ReentrancyGuardTransient.sol", "lastModifiedGitTimestamp": 1730497227 }, { "srcPath": "src/utils/SafeCastLib.sol", "lastModifiedGitTimestamp": 1715433563 }, { "srcPath": "src/utils/Initializable.sol", "scores": { "extcodesize": 1 }, "lastModifiedGitTimestamp": 1705139261 }, { "srcPath": "src/utils/RedBlackTreeLib.sol", "scores": { "codesize": 1 }, "lastModifiedGitTimestamp": 1717740645 }, { "srcPath": "src/utils/ReentrancyGuard.sol", "scores": { "codesize": 1 }, "lastModifiedGitTimestamp": 1706263836 }, { "srcPath": "src/tokens/ERC20.sol", "scores": { "staticcall": 1 }, "lastModifiedGitTimestamp": 1729135343 }, { "srcPath": "src/tokens/ERC20Votes.sol", "scores": { "staticcall": 1 }, "lastModifiedGitTimestamp": 1729135343 }, { "srcPath": "src/tokens/ERC4626.sol", "scores": { "staticcall": 1 }, "lastModifiedGitTimestamp": 1717740645 }, { "srcPath": "src/utils/MetadataReaderLib.sol", "scores": { "staticcall": 2 }, "lastModifiedGitTimestamp": 1723462389 }, { "srcPath": "src/accounts/ERC4337Factory.sol", "scores": { "codesize": 1, "call": 1 }, "lastModifiedGitTimestamp": 1703276182 }, { "srcPath": "src/accounts/ERC6551Proxy.sol", "scores": { "codesize": 1, "delegatecall": 1 }, "lastModifiedGitTimestamp": 1710219546 }, { "srcPath": "src/utils/Multicallable.sol", "scores": { "codesize": 1, "delegatecall": 1 }, "lastModifiedGitTimestamp": 1725108562 }, { "srcPath": "src/utils/UpgradeableBeacon.sol", "scores": { "codesize": 2, "extcodesize": 1 }, "lastModifiedGitTimestamp": 1715045031 }, { "srcPath": "src/auth/EnumerableRoles.sol", "scores": { "staticcall": 2 }, "lastModifiedGitTimestamp": 1728811386 }, { "srcPath": "src/tokens/WETH.sol", "scores": { "codesize": 2, "call": 1 }, "lastModifiedGitTimestamp": 1719095021 }, { "srcPath": "src/utils/CREATE3.sol", "scores": { "extcodesize": 1, "create2": 1, "call": 1 }, "lastModifiedGitTimestamp": 1720878475 }, { "srcPath": "src/utils/DynamicArrayLib.sol", "scores": { "codesize": 2, "codecopy": 2 }, "lastModifiedGitTimestamp": 1728355500 }, { "srcPath": "src/utils/GasBurnerLib.sol", "scores": { "codecopy": 2, "staticcall": 1 }, "lastModifiedGitTimestamp": 1721303834 }, { "srcPath": "src/utils/WebAuthn.sol", "scores": { "staticcall": 2 }, "lastModifiedGitTimestamp": 1730239265 }, { "srcPath": "src/accounts/Pod.sol", "scores": { "codesize": 2, "call": 2 }, "lastModifiedGitTimestamp": 1727862888 }, { "srcPath": "src/utils/DeploylessPredeployQueryer.sol", "scores": { "codesize": 1, "extcodesize": 1, "call": 2 }, "lastModifiedGitTimestamp": 1713208829 }, { "srcPath": "src/utils/ERC1967Factory.sol", "scores": { "create": 1, "create2": 1, "call": 2 }, "lastModifiedGitTimestamp": 1706770409 }, { "srcPath": "src/utils/UUPSUpgradeable.sol", "scores": { "codesize": 2, "staticcall": 1, "delegatecall": 1 }, "lastModifiedGitTimestamp": 1715045031 }, { "srcPath": "src/utils/P256.sol", "scores": { "staticcall": 4 }, "lastModifiedGitTimestamp": 1723742125 }, { "srcPath": "src/utils/LibZip.sol", "scores": { "codesize": 4, "codecopy": 3, "delegatecall": 1 }, "lastModifiedGitTimestamp": 1707000199 }, { "srcPath": "src/accounts/LibERC6551.sol", "scores": { "extcodesize": 2, "extcodecopy": 7, "call": 1 }, "lastModifiedGitTimestamp": 1709789868 }, { "srcPath": "src/tokens/ERC721.sol", "scores": { "codesize": 6, "extcodesize": 1, "call": 1, "staticcall": 1 }, "lastModifiedGitTimestamp": 1711338124 }, { "srcPath": "src/utils/SSTORE2.sol", "scores": { "codesize": 1, "extcodesize": 4, "extcodecopy": 3, "create": 1, "create2": 2, "call": 1 }, "lastModifiedGitTimestamp": 1728067022 }, { "srcPath": "src/accounts/ERC1271.sol", "scores": { "codesize": 1, "gaslimit": 2, "gasprice": 8, "staticcall": 2 }, "lastModifiedGitTimestamp": 1730050055 }, { "srcPath": "src/accounts/ERC6551.sol", "scores": { "codesize": 2, "extcodecopy": 3, "call": 2, "staticcall": 3 }, "lastModifiedGitTimestamp": 1717372305 }, { "srcPath": "src/utils/ECDSA.sol", "scores": { "staticcall": 8 }, "lastModifiedGitTimestamp": 1730845513 }, { "srcPath": "src/utils/Lifebuoy.sol", "scores": { "codesize": 4, "extcodesize": 3, "call": 5, "staticcall": 1 }, "lastModifiedGitTimestamp": 1724378720 }, { "srcPath": "src/accounts/ERC4337.sol", "scores": { "codesize": 11, "extcodesize": 2, "call": 5, "staticcall": 1, "delegatecall": 1 }, "lastModifiedGitTimestamp": 1713297028 }, { "srcPath": "src/tokens/ERC1155.sol", "scores": { "extcodesize": 3, "call": 4, "staticcall": 10 }, "lastModifiedGitTimestamp": 1718114922 }, { "srcPath": "src/utils/ext/delegatexyz/DelegateCheckerLib.sol", "scores": { "staticcall": 20 }, "lastModifiedGitTimestamp": 1720170364 }, { "srcPath": "src/utils/SignatureCheckerLib.sol", "scores": { "codesize": 2, "extcodesize": 2, "call": 3, "staticcall": 21 }, "lastModifiedGitTimestamp": 1730845513 }, { "srcPath": "src/utils/SafeTransferLib.sol", "scores": { "codesize": 29, "extcodesize": 11, "create": 4, "call": 21, "staticcall": 6 }, "lastModifiedGitTimestamp": 1729206025 }, { "srcPath": "src/utils/LibClone.sol", "scores": { "codesize": 23, "codecopy": 3, "extcodesize": 25, "extcodecopy": 16, "create": 11, "create2": 21, "call": 11, "staticcall": 16 }, "lastModifiedGitTimestamp": 1730767406 } ]