diff --git a/campaigns/full-spectrum.toml b/campaigns/full-spectrum.toml new file mode 100644 index 00000000..b682ab76 --- /dev/null +++ b/campaigns/full-spectrum.toml @@ -0,0 +1,152 @@ +name = "full-spectrum" +description = "4-stage campaign covering all scenario categories: warmup with simple ops, ramp into DeFi, peak with full protocol mix, cooldown" + +[spam] +mode = "tps" +rate = 100 +duration = 120 +seed = 42 + +# ────────────────────────────────────────────────────────────── +# Stage 1: Warmup — simple token operations +# ────────────────────────────────────────────────────────────── +[[spam.stage]] +name = "warmup" +rate = 50 +duration = 60 + +[[spam.stage.mix]] +scenario = "erc20" +share_pct = 30.0 + +[[spam.stage.mix]] +scenario = "scenarios/erc721.toml" +share_pct = 25.0 + +[[spam.stage.mix]] +scenario = "scenarios/erc1155.toml" +share_pct = 25.0 + +[[spam.stage.mix]] +scenario = "scenarios/stablecoin.toml" +share_pct = 20.0 + +# ────────────────────────────────────────────────────────────── +# Stage 2: Ramp — DeFi protocols come online +# ────────────────────────────────────────────────────────────── +[[spam.stage]] +name = "defi-ramp" +rate = 150 +duration = 120 + +[[spam.stage.mix]] +scenario = "scenarios/simpleAMM.toml" +share_pct = 25.0 + +[[spam.stage.mix]] +scenario = "scenarios/lending.toml" +share_pct = 20.0 + +[[spam.stage.mix]] +scenario = "scenarios/staking.toml" +share_pct = 15.0 + +[[spam.stage.mix]] +scenario = "scenarios/erc4626vault.toml" +share_pct = 15.0 + +[[spam.stage.mix]] +scenario = "scenarios/orderBook.toml" +share_pct = 15.0 + +[[spam.stage.mix]] +scenario = "scenarios/bridge.toml" +share_pct = 10.0 + +# ────────────────────────────────────────────────────────────── +# Stage 3: Peak — everything at once, max diversity +# ────────────────────────────────────────────────────────────── +[[spam.stage]] +name = "full-load" +rate = 300 +duration = 180 + +[[spam.stage.mix]] +scenario = "scenarios/simpleAMM.toml" +share_pct = 15.0 + +[[spam.stage.mix]] +scenario = "scenarios/lending.toml" +share_pct = 12.0 + +[[spam.stage.mix]] +scenario = "scenarios/orderBook.toml" +share_pct = 10.0 + +[[spam.stage.mix]] +scenario = "scenarios/staking.toml" +share_pct = 8.0 + +[[spam.stage.mix]] +scenario = "scenarios/erc4626vault.toml" +share_pct = 8.0 + +[[spam.stage.mix]] +scenario = "scenarios/governance.toml" +share_pct = 7.0 + +[[spam.stage.mix]] +scenario = "scenarios/multisig.toml" +share_pct = 7.0 + +[[spam.stage.mix]] +scenario = "scenarios/bridge.toml" +share_pct = 7.0 + +[[spam.stage.mix]] +scenario = "scenarios/dutchAuction.toml" +share_pct = 5.0 + +[[spam.stage.mix]] +scenario = "scenarios/nameRegistry.toml" +share_pct = 5.0 + +[[spam.stage.mix]] +scenario = "scenarios/precompiles/hashPrecompiles.toml" +share_pct = 5.0 + +[[spam.stage.mix]] +scenario = "scenarios/stablecoin.toml" +share_pct = 5.0 + +[[spam.stage.mix]] +scenario = "scenarios/erc721.toml" +share_pct = 3.0 + +[[spam.stage.mix]] +scenario = "scenarios/erc1155.toml" +share_pct = 3.0 + +# ────────────────────────────────────────────────────────────── +# Stage 4: Cooldown — light governance + staking tail +# ────────────────────────────────────────────────────────────── +[[spam.stage]] +name = "cooldown" +rate = 30 +duration = 60 + +[[spam.stage.mix]] +scenario = "scenarios/governance.toml" +share_pct = 30.0 + +[[spam.stage.mix]] +scenario = "scenarios/staking.toml" +share_pct = 30.0 + +[[spam.stage.mix]] +scenario = "scenarios/nameRegistry.toml" +share_pct = 20.0 + +[[spam.stage.mix]] +scenario = "erc20" +share_pct = 20.0 diff --git a/scenarios/bondingCurve.toml b/scenarios/bondingCurve.toml new file mode 100644 index 00000000..db619911 --- /dev/null +++ b/scenarios/bondingCurve.toml @@ -0,0 +1,161 @@ +# ============================================================ +# Bonding Curve Token Launch (pump.fun style) - Stress Test +# ============================================================ +# Source: /tmp/bondingcurve.sol (Solidity 0.8.26, optimized with 200 runs) +# Gas profile: math-heavy per-trade price computation (linear bonding curve), +# CREATE2 contract deployments, ETH transfers via low-level call, +# ERC20 mint/burn per buy/sell — completely different from constant-product AMMs. +# +# Contracts: +# - BondingCurveToken: ERC20 with linear bonding curve buy()/sell() +# Price formula: price = basePrice + (totalSupply * slope) / 1e18 +# - TokenLaunchpad: Factory deploying BondingCurveTokens via CREATE2 +# +# Three spam patterns: +# 1. createToken — deploy new bonding curve tokens via CREATE2 (fuzzed salt) +# 2. buy — buy tokens on a seeded bonding curve token (fuzzed ETH value) +# 3. sell — sell tokens back to the curve (fuzzed amount, may revert) +# +# compiled with: solc --bin --optimize --optimize-runs 200 /tmp/bondingcurve.sol +# ============================================================ + +[env] +# Base price: 0.000001 ETH per token (1e12 wei) +basePrice = "1000000000000" +# Slope: 1e9 (price increases 1e9 wei per 1e18 totalSupply) +slope = "1000000000" +# Alternative slopes for setup tokens deployed via launchpad +slope2 = "2000000000" +slope3 = "500000000" +slope4 = "3000000000" +slope5 = "1500000000" +# Salts for setup token creation (via launchpad) +salt1 = "0x0000000000000000000000000000000000000000000000000000000000000001" +salt2 = "0x0000000000000000000000000000000000000000000000000000000000000002" +salt3 = "0x0000000000000000000000000000000000000000000000000000000000000003" +salt4 = "0x0000000000000000000000000000000000000000000000000000000000000004" +salt5 = "0x0000000000000000000000000000000000000000000000000000000000000005" + + +### Deploy contracts ########################################################### + +# Deploy a standalone BondingCurveToken for buy/sell spam +[[create]] +name = "BondingCurveToken" +signature = "(uint256 basePrice_, uint256 slope_)" +args = ["{basePrice}", "{slope}"] +# BondingCurveToken bytecode +bytecode = "0x608060405234801561000f575f80fd5b50604051610e16380380610e1683398101604081905261002e91610099565b6040805180820190915260118152702137b73234b733a1bab93b32aa37b5b2b760791b60208201525f906100629082610153565b506040805180820190915260038152621090d560ea1b602082015260019061008a9082610153565b5060059190915560065561020d565b5f80604083850312156100aa575f80fd5b505080516020909101519092909150565b634e487b7160e01b5f52604160045260245ffd5b600181811c908216806100e357607f821691505b60208210810361010157634e487b7160e01b5f52602260045260245ffd5b50919050565b601f82111561014e57805f5260205f20601f840160051c8101602085101561012c5750805b601f840160051c820191505b8181101561014b575f8155600101610138565b50505b505050565b81516001600160401b0381111561016c5761016c6100bb565b6101808161017a84546100cf565b84610107565b6020601f8211600181146101b2575f831561019b5750848201515b5f19600385901b1c1916600184901b17845561014b565b5f84815260208120601f198516915b828110156101e157878501518255602094850194600190920191016101c1565b50848210156101fe57868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b610bfc8061021a5f395ff3fe6080604052600436106100e7575f3560e01c806390825c2811610087578063c7876ea411610057578063c7876ea414610244578063dd62ed3e14610259578063e4849b321461028f578063eb91d37e146102ae575f80fd5b806390825c28146101f357806395d89b4114610207578063a6f2ae3a1461021b578063a9059cbb14610225575f80fd5b806323b872dd116100c257806323b872dd1461016e578063313ce5671461018d57806370a08231146101b357806383caf275146101de575f80fd5b806306fdde03146100f2578063095ea7b31461011c57806318160ddd1461014b575f80fd5b366100ee57005b5f80fd5b3480156100fd575f80fd5b506101066102c2565b6040516101139190610a0b565b60405180910390f35b348015610127575f80fd5b5061013b610136366004610a5b565b61034d565b6040519015158152602001610113565b348015610156575f80fd5b5061016060025481565b604051908152602001610113565b348015610179575f80fd5b5061013b610188366004610a83565b6103b9565b348015610198575f80fd5b506101a1601281565b60405160ff9091168152602001610113565b3480156101be575f80fd5b506101606101cd366004610abd565b60036020525f908152604090205481565b3480156101e9575f80fd5b5061016060065481565b3480156101fe575f80fd5b50610160610474565b348015610212575f80fd5b506101066104a2565b6102236104af565b005b348015610230575f80fd5b5061013b61023f366004610a5b565b610654565b34801561024f575f80fd5b5061016060055481565b348015610264575f80fd5b50610160610273366004610ad6565b600460209081525f928352604080842090915290825290205481565b34801561029a575f80fd5b506102236102a9366004610b07565b610667565b3480156102b9575f80fd5b506101606108cb565b5f80546102ce90610b1e565b80601f01602080910402602001604051908101604052809291908181526020018280546102fa90610b1e565b80156103455780601f1061031c57610100808354040283529160200191610345565b820191905f5260205f20905b81548152906001019060200180831161032857829003601f168201915b505050505081565b335f8181526004602090815260408083206001600160a01b038716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925906103a79086815260200190565b60405180910390a35060015b92915050565b6001600160a01b0383165f9081526004602090815260408083203384529091528120545f19811461046057828110156104325760405162461bcd60e51b8152602060048201526016602482015275696e73756666696369656e7420616c6c6f77616e636560501b60448201526064015b60405180910390fd5b61043c8382610b6a565b6001600160a01b0386165f9081526004602090815260408083203384529091529020555b61046b8585856108fc565b95945050505050565b5f670de0b6b3a76400006104866108cb565b6002546104939190610b7d565b61049d9190610b94565b905090565b600180546102ce90610b1e565b5f34116104e95760405162461bcd60e51b81526020600482015260086024820152670e6cadcc8408aa8960c31b6044820152606401610429565b5f6104f26108cb565b90505f81116105305760405162461bcd60e51b815260206004820152600a6024820152697a65726f20707269636560b01b6044820152606401610429565b5f8161054434670de0b6b3a7640000610b7d565b61054e9190610b94565b90505f81116105905760405162461bcd60e51b815260206004820152600e60248201526d0e8dede40d8d2e8e8d8ca408aa8960931b6044820152606401610429565b8060025f8282546105a19190610bb3565b9091555050335f90815260036020526040812080548392906105c4908490610bb3565b909155505060405181815233905f907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35f6106096108cb565b604080513481526020810185905290810182905290915033907fbeae048c6d270d9469f86cf6e8fedda3c60ad770f16c24c9fc131c8e9a09101d9060600160405180910390a2505050565b5f6106603384846108fc565b9392505050565b5f811180156106845750335f908152600360205260409020548111155b6106bd5760405162461bcd60e51b815260206004820152600a60248201526918985908185b5bdd5b9d60b21b6044820152606401610429565b5f6106c66108cb565b90505f670de0b6b3a76400006106dc8385610b7d565b6106e69190610b94565b90505f81116107285760405162461bcd60e51b815260206004820152600e60248201526d746f6f2066657720746f6b656e7360901b6044820152606401610429565b804710156107785760405162461bcd60e51b815260206004820152601860248201527f696e73756666696369656e7420455448207265736572766500000000000000006044820152606401610429565b335f9081526003602052604081208054859290610796908490610b6a565b925050819055508260025f8282546107ae9190610b6a565b90915550506040518381525f9033907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a36040515f90339083908381818185875af1925050503d805f8114610829576040519150601f19603f3d011682016040523d82523d5f602084013e61082e565b606091505b50509050806108755760405162461bcd60e51b8152602060048201526013602482015272115512081d1c985b9cd9995c8819985a5b1959606a1b6044820152606401610429565b5f61087e6108cb565b604080518781526020810186905290810182905290915033907f846c37eef631e0943682d87352ec117c20008eb7f425c9b85ac011a6d4774cc09060600160405180910390a25050505050565b5f670de0b6b3a76400006006546002546108e59190610b7d565b6108ef9190610b94565b60055461049d9190610bb3565b6001600160a01b0383165f9081526003602052604081205482111561095a5760405162461bcd60e51b8152602060048201526014602482015273696e73756666696369656e742062616c616e636560601b6044820152606401610429565b6001600160a01b0384165f9081526003602052604081208054849290610981908490610b6a565b90915550506001600160a01b0383165f90815260036020526040812080548492906109ad908490610bb3565b92505081905550826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516109f991815260200190565b60405180910390a35060019392505050565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f83011684010191505092915050565b80356001600160a01b0381168114610a56575f80fd5b919050565b5f8060408385031215610a6c575f80fd5b610a7583610a40565b946020939093013593505050565b5f805f60608486031215610a95575f80fd5b610a9e84610a40565b9250610aac60208501610a40565b929592945050506040919091013590565b5f60208284031215610acd575f80fd5b61066082610a40565b5f8060408385031215610ae7575f80fd5b610af083610a40565b9150610afe60208401610a40565b90509250929050565b5f60208284031215610b17575f80fd5b5035919050565b600181811c90821680610b3257607f821691505b602082108103610b5057634e487b7160e01b5f52602260045260245ffd5b50919050565b634e487b7160e01b5f52601160045260245ffd5b818103818111156103b3576103b3610b56565b80820281158282048414176103b3576103b3610b56565b5f82610bae57634e487b7160e01b5f52601260045260245ffd5b500490565b808201808211156103b3576103b3610b5656fea26469706673582212207e494aca00d4337e7443e67f2e4e9448090ccc1929d25566646da8b833c95bd264736f6c634300081a0033" + +# Deploy TokenLaunchpad factory (no constructor args) +[[create]] +name = "TokenLaunchpad" +bytecode = "0x6080604052348015600e575f80fd5b5061169b8061001c5f395ff3fe608060405260043610610057575f3560e01c806319f37361146100625780634f64b2be146100a5578063634442b1146100dc5780637e72fb52146100ef5780639f181b5e14610104578063f464e7db14610120575f80fd5b3661005e57005b5f80fd5b34801561006d575f80fd5b5061009061007c36600461075a565b60016020525f908152604090205460ff1681565b60405190151581526020015b60405180910390f35b3480156100b0575f80fd5b506100c46100bf36600461077c565b61013f565b6040516001600160a01b03909116815260200161009c565b6100c46100ea366004610793565b610166565b6101026100fd36600461075a565b6103ff565b005b34801561010f575f80fd5b505f5460405190815260200161009c565b34801561012b575f80fd5b5061010261013a3660046107bc565b61058a565b5f818154811061014d575f80fd5b5f918252602090912001546001600160a01b0316905081565b5f806040518060200161017890610736565b601f1982820381018352601f90910116604081815260208201879052810185905260600160408051601f19818403018152908290526101ba92916020016107fd565b60405160208183030381529060405290505f858251602084015ff590506001600160a01b0381166102235760405162461bcd60e51b815260206004820152600e60248201526d18dc99585d194c8819985a5b195960921b60448201526064015b60405180910390fd5b5f8054600180820183557f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e56390910180546001600160a01b0319166001600160a01b0385169081179091558083526020828152604093849020805460ff19169093179092558251888152918201879052917fd5054ba42059be88c66c1a10236e5a0cea44d10897996e6040b6f41c57be1342910160405180910390a234156103f657806001600160a01b031663a6f2ae3a346040518263ffffffff1660e01b81526004015f604051808303818588803b1580156102fd575f80fd5b505af115801561030f573d5f803e3d5ffd5b50506040516370a0823160e01b81523060048201525f93506001600160a01b03851692506370a082319150602401602060405180830381865afa158015610358573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061037c9190610819565b905080156103f45760405163a9059cbb60e01b8152336004820152602481018290526001600160a01b0383169063a9059cbb906044016020604051808303815f875af11580156103ce573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906103f29190610830565b505b505b95945050505050565b6001600160a01b0381165f9081526001602052604090205460ff166104565760405162461bcd60e51b815260206004820152600d60248201526c3ab735b737bbb7103a37b5b2b760991b604482015260640161021a565b806001600160a01b031663a6f2ae3a346040518263ffffffff1660e01b81526004015f604051808303818588803b15801561048f575f80fd5b505af11580156104a1573d5f803e3d5ffd5b50506040516370a0823160e01b81523060048201525f93506001600160a01b03851692506370a082319150602401602060405180830381865afa1580156104ea573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061050e9190610819565b905080156105865760405163a9059cbb60e01b8152336004820152602481018290526001600160a01b0383169063a9059cbb906044016020604051808303815f875af1158015610560573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906105849190610830565b505b5050565b6001600160a01b0382165f9081526001602052604090205460ff166105e15760405162461bcd60e51b815260206004820152600d60248201526c3ab735b737bbb7103a37b5b2b760991b604482015260640161021a565b6040516323b872dd60e01b8152336004820152306024820152604481018290526001600160a01b038316906323b872dd906064016020604051808303815f875af1158015610631573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906106559190610830565b506040516372424d9960e11b8152600481018290526001600160a01b0383169063e4849b32906024015f604051808303815f87803b158015610695575f80fd5b505af11580156106a7573d5f803e3d5ffd5b50506040515f925033915047908381818185875af1925050503d805f81146106ea576040519150601f19603f3d011682016040523d82523d5f602084013e6106ef565b606091505b50509050806105845760405162461bcd60e51b8152602060048201526013602482015272115512081d1c985b9cd9995c8819985a5b1959606a1b604482015260640161021a565b610e168061085083390190565b6001600160a01b0381168114610757575f80fd5b50565b5f6020828403121561076a575f80fd5b813561077581610743565b9392505050565b5f6020828403121561078c575f80fd5b5035919050565b5f805f606084860312156107a5575f80fd5b505081359360208301359350604090920135919050565b5f80604083850312156107cd575f80fd5b82356107d881610743565b946020939093013593505050565b5f81518060208401855e5f93019283525090919050565b5f61081161080b83866107e6565b846107e6565b949350505050565b5f60208284031215610829575f80fd5b5051919050565b5f60208284031215610840575f80fd5b81518015158114610775575f80fdfe608060405234801561000f575f80fd5b50604051610e16380380610e1683398101604081905261002e91610099565b6040805180820190915260118152702137b73234b733a1bab93b32aa37b5b2b760791b60208201525f906100629082610153565b506040805180820190915260038152621090d560ea1b602082015260019061008a9082610153565b5060059190915560065561020d565b5f80604083850312156100aa575f80fd5b505080516020909101519092909150565b634e487b7160e01b5f52604160045260245ffd5b600181811c908216806100e357607f821691505b60208210810361010157634e487b7160e01b5f52602260045260245ffd5b50919050565b601f82111561014e57805f5260205f20601f840160051c8101602085101561012c5750805b601f840160051c820191505b8181101561014b575f8155600101610138565b50505b505050565b81516001600160401b0381111561016c5761016c6100bb565b6101808161017a84546100cf565b84610107565b6020601f8211600181146101b2575f831561019b5750848201515b5f19600385901b1c1916600184901b17845561014b565b5f84815260208120601f198516915b828110156101e157878501518255602094850194600190920191016101c1565b50848210156101fe57868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b610bfc8061021a5f395ff3fe6080604052600436106100e7575f3560e01c806390825c2811610087578063c7876ea411610057578063c7876ea414610244578063dd62ed3e14610259578063e4849b321461028f578063eb91d37e146102ae575f80fd5b806390825c28146101f357806395d89b4114610207578063a6f2ae3a1461021b578063a9059cbb14610225575f80fd5b806323b872dd116100c257806323b872dd1461016e578063313ce5671461018d57806370a08231146101b357806383caf275146101de575f80fd5b806306fdde03146100f2578063095ea7b31461011c57806318160ddd1461014b575f80fd5b366100ee57005b5f80fd5b3480156100fd575f80fd5b506101066102c2565b6040516101139190610a0b565b60405180910390f35b348015610127575f80fd5b5061013b610136366004610a5b565b61034d565b6040519015158152602001610113565b348015610156575f80fd5b5061016060025481565b604051908152602001610113565b348015610179575f80fd5b5061013b610188366004610a83565b6103b9565b348015610198575f80fd5b506101a1601281565b60405160ff9091168152602001610113565b3480156101be575f80fd5b506101606101cd366004610abd565b60036020525f908152604090205481565b3480156101e9575f80fd5b5061016060065481565b3480156101fe575f80fd5b50610160610474565b348015610212575f80fd5b506101066104a2565b6102236104af565b005b348015610230575f80fd5b5061013b61023f366004610a5b565b610654565b34801561024f575f80fd5b5061016060055481565b348015610264575f80fd5b50610160610273366004610ad6565b600460209081525f928352604080842090915290825290205481565b34801561029a575f80fd5b506102236102a9366004610b07565b610667565b3480156102b9575f80fd5b506101606108cb565b5f80546102ce90610b1e565b80601f01602080910402602001604051908101604052809291908181526020018280546102fa90610b1e565b80156103455780601f1061031c57610100808354040283529160200191610345565b820191905f5260205f20905b81548152906001019060200180831161032857829003601f168201915b505050505081565b335f8181526004602090815260408083206001600160a01b038716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925906103a79086815260200190565b60405180910390a35060015b92915050565b6001600160a01b0383165f9081526004602090815260408083203384529091528120545f19811461046057828110156104325760405162461bcd60e51b8152602060048201526016602482015275696e73756666696369656e7420616c6c6f77616e636560501b60448201526064015b60405180910390fd5b61043c8382610b6a565b6001600160a01b0386165f9081526004602090815260408083203384529091529020555b61046b8585856108fc565b95945050505050565b5f670de0b6b3a76400006104866108cb565b6002546104939190610b7d565b61049d9190610b94565b905090565b600180546102ce90610b1e565b5f34116104e95760405162461bcd60e51b81526020600482015260086024820152670e6cadcc8408aa8960c31b6044820152606401610429565b5f6104f26108cb565b90505f81116105305760405162461bcd60e51b815260206004820152600a6024820152697a65726f20707269636560b01b6044820152606401610429565b5f8161054434670de0b6b3a7640000610b7d565b61054e9190610b94565b90505f81116105905760405162461bcd60e51b815260206004820152600e60248201526d0e8dede40d8d2e8e8d8ca408aa8960931b6044820152606401610429565b8060025f8282546105a19190610bb3565b9091555050335f90815260036020526040812080548392906105c4908490610bb3565b909155505060405181815233905f907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35f6106096108cb565b604080513481526020810185905290810182905290915033907fbeae048c6d270d9469f86cf6e8fedda3c60ad770f16c24c9fc131c8e9a09101d9060600160405180910390a2505050565b5f6106603384846108fc565b9392505050565b5f811180156106845750335f908152600360205260409020548111155b6106bd5760405162461bcd60e51b815260206004820152600a60248201526918985908185b5bdd5b9d60b21b6044820152606401610429565b5f6106c66108cb565b90505f670de0b6b3a76400006106dc8385610b7d565b6106e69190610b94565b90505f81116107285760405162461bcd60e51b815260206004820152600e60248201526d746f6f2066657720746f6b656e7360901b6044820152606401610429565b804710156107785760405162461bcd60e51b815260206004820152601860248201527f696e73756666696369656e7420455448207265736572766500000000000000006044820152606401610429565b335f9081526003602052604081208054859290610796908490610b6a565b925050819055508260025f8282546107ae9190610b6a565b90915550506040518381525f9033907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a36040515f90339083908381818185875af1925050503d805f8114610829576040519150601f19603f3d011682016040523d82523d5f602084013e61082e565b606091505b50509050806108755760405162461bcd60e51b8152602060048201526013602482015272115512081d1c985b9cd9995c8819985a5b1959606a1b6044820152606401610429565b5f61087e6108cb565b604080518781526020810186905290810182905290915033907f846c37eef631e0943682d87352ec117c20008eb7f425c9b85ac011a6d4774cc09060600160405180910390a25050505050565b5f670de0b6b3a76400006006546002546108e59190610b7d565b6108ef9190610b94565b60055461049d9190610bb3565b6001600160a01b0383165f9081526003602052604081205482111561095a5760405162461bcd60e51b8152602060048201526014602482015273696e73756666696369656e742062616c616e636560601b6044820152606401610429565b6001600160a01b0384165f9081526003602052604081208054849290610981908490610b6a565b90915550506001600160a01b0383165f90815260036020526040812080548492906109ad908490610bb3565b92505081905550826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516109f991815260200190565b60405180910390a35060019392505050565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f83011684010191505092915050565b80356001600160a01b0381168114610a56575f80fd5b919050565b5f8060408385031215610a6c575f80fd5b610a7583610a40565b946020939093013593505050565b5f805f60608486031215610a95575f80fd5b610a9e84610a40565b9250610aac60208501610a40565b929592945050506040919091013590565b5f60208284031215610acd575f80fd5b61066082610a40565b5f8060408385031215610ae7575f80fd5b610af083610a40565b9150610afe60208401610a40565b90509250929050565b5f60208284031215610b17575f80fd5b5035919050565b600181811c90821680610b3257607f821691505b602082108103610b5057634e487b7160e01b5f52602260045260245ffd5b50919050565b634e487b7160e01b5f52601160045260245ffd5b818103818111156103b3576103b3610b56565b80820281158282048414176103b3576103b3610b56565b5f82610bae57634e487b7160e01b5f52601260045260245ffd5b500490565b808201808211156103b3576103b3610b5656fea26469706673582212207e494aca00d4337e7443e67f2e4e9448090ccc1929d25566646da8b833c95bd264736f6c634300081a0033a2646970667358221220a9fb3344bce830c9d0c2276c0cdace4eb593d0494f79d0c8a7539638e71eea1a64736f6c634300081a0033" + + +### Setup: seed initial liquidity + create tokens via launchpad ################ + +# Admin buys into the standalone BondingCurveToken to seed liquidity +[[setup]] +kind = "admin_seed_liquidity_1" +to = "{BondingCurveToken}" +signature = "buy() payable" +args = [] +value = "1 eth" +gas_limit = 200000 + +# Admin buys more to build up the curve +[[setup]] +kind = "admin_seed_liquidity_2" +to = "{BondingCurveToken}" +signature = "buy() payable" +args = [] +value = "1 eth" +gas_limit = 200000 + +# Create 5 tokens via launchpad with different slopes (seeds initial liquidity via value) +[[setup]] +kind = "launchpad_create_token_1" +to = "{TokenLaunchpad}" +signature = "createToken(bytes32 salt, uint256 basePrice, uint256 slope) returns (address)" +args = ["{salt1}", "{basePrice}", "{slope}"] +value = "0.1 eth" +gas_limit = 1000000 + +[[setup]] +kind = "launchpad_create_token_2" +to = "{TokenLaunchpad}" +signature = "createToken(bytes32 salt, uint256 basePrice, uint256 slope) returns (address)" +args = ["{salt2}", "{basePrice}", "{slope2}"] +value = "0.1 eth" +gas_limit = 1000000 + +[[setup]] +kind = "launchpad_create_token_3" +to = "{TokenLaunchpad}" +signature = "createToken(bytes32 salt, uint256 basePrice, uint256 slope) returns (address)" +args = ["{salt3}", "{basePrice}", "{slope3}"] +value = "0.1 eth" +gas_limit = 1000000 + +[[setup]] +kind = "launchpad_create_token_4" +to = "{TokenLaunchpad}" +signature = "createToken(bytes32 salt, uint256 basePrice, uint256 slope) returns (address)" +args = ["{salt4}", "{basePrice}", "{slope4}"] +value = "0.1 eth" +gas_limit = 1000000 + +[[setup]] +kind = "launchpad_create_token_5" +to = "{TokenLaunchpad}" +signature = "createToken(bytes32 salt, uint256 basePrice, uint256 slope) returns (address)" +args = ["{salt5}", "{basePrice}", "{slope5}"] +value = "0.1 eth" +gas_limit = 1000000 + + +### Spam patterns ############################################################## + +# 1. Create new bonding curve tokens via CREATE2 with fuzzed salt + initial buy +# Exercises contract creation opcodes (CREATE2) — key pattern for this scenario. +# Every tx deploys a unique BondingCurveToken (deterministic from salt). +[[spam]] +[spam.tx] +kind = "create_token" +to = "{TokenLaunchpad}" +from_pool = "spammer" +signature = "createToken(bytes32 salt, uint256 basePrice, uint256 slope) returns (address)" +args = ["{salt1}", "{basePrice}", "{slope}"] +value = "0.01 eth" +gas_limit = 500000 +fuzz = [ + { param = "salt", min = "0", max = "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" }, +] + +# 2. Buy tokens on the standalone BondingCurveToken directly +# Fuzz ETH value from 0.001 to 0.05 ETH — exercises bonding curve price math, +# totalSupply updates, balance minting, and event emission. +[[spam]] +[spam.tx] +kind = "buy_token" +to = "{BondingCurveToken}" +from_pool = "spammer" +signature = "function buy() external payable" +args = [] +value = "0.01 eth" +gas_limit = 200000 +fuzz = [{ value = true, min = "1000000000000000", max = "50000000000000000" }] + +# 3. Sell tokens back to the bonding curve +# Fuzz amount — will revert if spammer has no balance or insufficient ETH in reserve. +# Exercises burn path, ETH transfer via low-level call, price recalculation. +[[spam]] +[spam.tx] +kind = "sell_token" +to = "{BondingCurveToken}" +from_pool = "spammer" +signature = "function sell(uint256 amount) external" +args = ["1000000000000000000"] +gas_limit = 250000 +fuzz = [{ param = "amount", min = "100000000000000000", max = "10000000000000000000" }] diff --git a/scenarios/bridge.toml b/scenarios/bridge.toml new file mode 100644 index 00000000..c0ddf7fd --- /dev/null +++ b/scenarios/bridge.toml @@ -0,0 +1,80 @@ +# ============================================================ +# L1->L2 Bridge Deposit Scenario +# ============================================================ +# Simulates bridge deposit traffic: ETH deposits, ERC20 deposits, +# and deposit processing. Event-heavy with storage writes for +# nonce tracking and deposit hash storage. +# Source: /tmp/bridge.sol (Solidity 0.8.26, optimized with 200 runs) +# ============================================================ + +[env] +initialSupply = "1000000000000000000000000000" +destinationChainId = "42161" + +# Deploy BridgeToken with initial supply +[[create]] +name = "BridgeToken" +bytecode = "0x60c0604052600b60809081526a213934b233b2aa37b5b2b760a91b60a0525f90610029908261016f565b5060408051808201909152600381526242524760e81b6020820152600190610051908261016f565b506002805460ff1916601217905534801561006a575f80fd5b506040516109bb3803806109bb83398101604081905261008991610229565b6003819055335f818152600460209081526040808320859055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a350610240565b634e487b7160e01b5f52604160045260245ffd5b600181811c908216806100ff57607f821691505b60208210810361011d57634e487b7160e01b5f52602260045260245ffd5b50919050565b601f82111561016a57805f5260205f20601f840160051c810160208510156101485750805b601f840160051c820191505b81811015610167575f8155600101610154565b50505b505050565b81516001600160401b03811115610188576101886100d7565b61019c8161019684546100eb565b84610123565b6020601f8211600181146101ce575f83156101b75750848201515b5f19600385901b1c1916600184901b178455610167565b5f84815260208120601f198516915b828110156101fd57878501518255602094850194600190920191016101dd565b508482101561021a57868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b5f60208284031215610239575f80fd5b5051919050565b61076e8061024d5f395ff3fe608060405234801561000f575f80fd5b506004361061009b575f3560e01c806340c10f191161006357806340c10f191461012957806370a082311461013e57806395d89b411461015d578063a9059cbb14610165578063dd62ed3e14610178575f80fd5b806306fdde031461009f578063095ea7b3146100bd57806318160ddd146100e057806323b872dd146100f7578063313ce5671461010a575b5f80fd5b6100a76101a2565b6040516100b491906105c3565b60405180910390f35b6100d06100cb366004610613565b61022d565b60405190151581526020016100b4565b6100e960035481565b6040519081526020016100b4565b6100d061010536600461063b565b610299565b6002546101179060ff1681565b60405160ff90911681526020016100b4565b61013c610137366004610613565b61044f565b005b6100e961014c366004610675565b60046020525f908152604090205481565b6100a76104d5565b6100d0610173366004610613565b6104e2565b6100e9610186366004610695565b600560209081525f928352604080842090915290825290205481565b5f80546101ae906106c6565b80601f01602080910402602001604051908101604052809291908181526020018280546101da906106c6565b80156102255780601f106101fc57610100808354040283529160200191610225565b820191905f5260205f20905b81548152906001019060200180831161020857829003601f168201915b505050505081565b335f8181526005602090815260408083206001600160a01b038716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925906102879086815260200190565b60405180910390a35060015b92915050565b6001600160a01b0383165f908152600460205260408120548211156102fc5760405162461bcd60e51b8152602060048201526014602482015273496e73756666696369656e742062616c616e636560601b60448201526064015b60405180910390fd5b6001600160a01b0384165f9081526005602090815260408083203384529091529020548211156103675760405162461bcd60e51b8152602060048201526016602482015275496e73756666696369656e7420616c6c6f77616e636560501b60448201526064016102f3565b6001600160a01b0384165f90815260056020908152604080832033845290915281208054849290610399908490610712565b90915550506001600160a01b0384165f90815260046020526040812080548492906103c5908490610712565b90915550506001600160a01b0383165f90815260046020526040812080548492906103f1908490610725565b92505081905550826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161043d91815260200190565b60405180910390a35060019392505050565b8060035f8282546104609190610725565b90915550506001600160a01b0382165f908152600460205260408120805483929061048c908490610725565b90915550506040518181526001600160a01b038316905f907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b600180546101ae906106c6565b335f908152600460205260408120548211156105375760405162461bcd60e51b8152602060048201526014602482015273496e73756666696369656e742062616c616e636560601b60448201526064016102f3565b335f9081526004602052604081208054849290610555908490610712565b90915550506001600160a01b0383165f9081526004602052604081208054849290610581908490610725565b90915550506040518281526001600160a01b0384169033907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602001610287565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f83011684010191505092915050565b80356001600160a01b038116811461060e575f80fd5b919050565b5f8060408385031215610624575f80fd5b61062d836105f8565b946020939093013593505050565b5f805f6060848603121561064d575f80fd5b610656846105f8565b9250610664602085016105f8565b929592945050506040919091013590565b5f60208284031215610685575f80fd5b61068e826105f8565b9392505050565b5f80604083850312156106a6575f80fd5b6106af836105f8565b91506106bd602084016105f8565b90509250929050565b600181811c908216806106da57607f821691505b6020821081036106f857634e487b7160e01b5f52602260045260245ffd5b50919050565b634e487b7160e01b5f52601160045260245ffd5b81810381811115610293576102936106fe565b80820180821115610293576102936106fe56fea2646970667358221220b5525893496b8c03e7490ee0afa301b608e821a0070a13eecd4bf31d8edc13a864736f6c634300081a0033" +args = ["{initialSupply}"] + +# Deploy SimpleBridge +[[create]] +name = "SimpleBridge" +bytecode = "0x6080604052348015600e575f80fd5b50610b368061001c5f395ff3fe60806040526004361061006e575f3560e01c8063873d8ea41161004c578063873d8ea4146100e9578063ae7e3baf14610108578063b581d2d114610136578063de35f5cb14610155575f80fd5b806321425ee01461007257806340c5faf0146100935780635358fbda146100d6575b5f80fd5b34801561007d575f80fd5b5061009161008c3660046107a8565b610177565b005b34801561009e575f80fd5b506100c16100ad3660046107d8565b60026020525f908152604090205460ff1681565b60405190151581526020015b60405180910390f35b6100916100e43660046107d8565b610404565b3480156100f4575f80fd5b50610091610103366004610923565b61055e565b348015610113575f80fd5b506100c16101223660046107d8565b60016020525f908152604090205460ff1681565b348015610141575f80fd5b50610091610150366004610a08565b6106d9565b348015610160575f80fd5b506101695f5481565b6040519081526020016100cd565b5f82116101be5760405162461bcd60e51b815260206004820152601060248201526f04d757374206465706f736974203e20360841b60448201526064015b60405180910390fd5b5f805481806101cc83610a3b565b909155506040516001600160601b031933606090811b8216602084015287901b1660348201526048810185905260688101849052608881018290524260a88201529091505f9060c80160408051808303601f1901815282825280516020918201205f818152600192839052928320805460ff19169092179091553360248401523060448401526064830187905292509081906001600160a01b0388169060840160408051601f198184030181529181526020820180516001600160e01b03166323b872dd60e01b179052516102a19190610a5f565b5f604051808303815f865af19150503d805f81146102da576040519150601f19603f3d011682016040523d82523d5f602084013e6102df565b606091505b50915091508180156103095750805115806103095750808060200190518101906103099190610a75565b6103475760405162461bcd60e51b815260206004820152600f60248201526e151c985b9cd9995c8819985a5b1959608a1b60448201526064016101b5565b6040516001600160601b031933606090811b8216602084015289901b1660348201526048810187905260688101869052608881018590524260a88201524360c88201523a60e88201525f90610108016040516020818303038152906040529050876001600160a01b0316336001600160a01b03167f83f979c86e35c88739c699828e098f274ca74b323949a3d7e0bcee8659291c5989898989876040516103f2959493929190610a9b565b60405180910390a35050505050505050565b5f34116104435760405162461bcd60e51b815260206004820152600d60248201526c09aeae6e840e6cadcc8408aa89609b1b60448201526064016101b5565b5f8054818061045183610a3b565b909155506040516001600160601b03193360601b16602082015234603482015260548101849052607481018290524260948201529091505f9060b40160408051808303601f1901815282825280516020918201205f8181526001808452938120805460ff19169094179093556001600160601b03193360601b169184019190915234603484015260548301869052607483018590524260948401524360b48401523a60d484015292509060f4016040516020818303038152906040529050336001600160a01b03167f9115d9081fb8f9b65e895000da18c06368188a5cff8812f41583d514cc472c3c3486868686604051610550959493929190610a9b565b60405180910390a250505050565b81518351148015610570575080518251145b6105ae5760405162461bcd60e51b815260206004820152600f60248201526e098cadccee8d040dad2e6dac2e8c6d608b1b60448201526064016101b5565b5f5b83518110156106d35760025f8583815181106105ce576105ce610aec565b60209081029190910181015182528101919091526040015f205460ff166106cb57600160025f86848151811061060657610606610aec565b602002602001015181526020019081526020015f205f6101000a81548160ff02191690831515021790555083818151811061064357610643610aec565b60200260200101517f7d77e3f1866839ef93f5eda23990fa4368bf7b0af583ae0f64ecae4da14a4d6184838151811061067e5761067e610aec565b602002602001015184848151811061069857610698610aec565b60200260200101516040516106c29291906001600160a01b03929092168252602082015260400190565b60405180910390a25b6001016105b0565b50505050565b5f8381526002602052604090205460ff161561072b5760405162461bcd60e51b8152602060048201526011602482015270105b1c9958591e481c1c9bd8d95cdcd959607a1b60448201526064016101b5565b5f83815260026020908152604091829020805460ff1916600117905581516001600160a01b038516815290810183905284917f7d77e3f1866839ef93f5eda23990fa4368bf7b0af583ae0f64ecae4da14a4d61910160405180910390a2505050565b80356001600160a01b03811681146107a3575f80fd5b919050565b5f805f606084860312156107ba575f80fd5b6107c38461078d565b95602085013595506040909401359392505050565b5f602082840312156107e8575f80fd5b5035919050565b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f1916810167ffffffffffffffff8111828210171561082c5761082c6107ef565b604052919050565b5f67ffffffffffffffff82111561084d5761084d6107ef565b5060051b60200190565b5f82601f830112610866575f80fd5b813561087961087482610834565b610803565b8082825260208201915060208360051b86010192508583111561089a575f80fd5b602085015b838110156108be576108b08161078d565b83526020928301920161089f565b5095945050505050565b5f82601f8301126108d7575f80fd5b81356108e561087482610834565b8082825260208201915060208360051b860101925085831115610906575f80fd5b602085015b838110156108be57803583526020928301920161090b565b5f805f60608486031215610935575f80fd5b833567ffffffffffffffff81111561094b575f80fd5b8401601f8101861361095b575f80fd5b803561096961087482610834565b8082825260208201915060208360051b85010192508883111561098a575f80fd5b6020840193505b828410156109ac578335825260209384019390910190610991565b9550505050602084013567ffffffffffffffff8111156109ca575f80fd5b6109d686828701610857565b925050604084013567ffffffffffffffff8111156109f2575f80fd5b6109fe868287016108c8565b9150509250925092565b5f805f60608486031215610a1a575f80fd5b83359250610a2a6020850161078d565b929592945050506040919091013590565b5f60018201610a5857634e487b7160e01b5f52601160045260245ffd5b5060010190565b5f82518060208501845e5f920191825250919050565b5f60208284031215610a85575f80fd5b81518015158114610a94575f80fd5b9392505050565b85815284602082015283604082015282606082015260a060808201525f82518060a0840152806020850160c085015e5f60c0828501015260c0601f19601f8301168401019150509695505050505050565b634e487b7160e01b5f52603260045260245ffdfea2646970667358221220c6237f765464f07265664dc7df1b6eb37bb7735d8d12b71e268b1e9404a36f1c64736f6c634300081a0033" + +# Setup: mint BridgeTokens to all spammer accounts +[[setup]] +kind = "mint_tokens" +to = "{BridgeToken}" +from_pool = "admin" +for_all_accounts = true +signature = "mint(address to, uint256 amount)" +args = ["{_sender}", "{initialSupply}"] + +# Setup: approve SimpleBridge to spend tokens for all spammer accounts +[[setup]] +kind = "approve_bridge" +to = "{BridgeToken}" +for_all_accounts = true +signature = "approve(address spender, uint256 amount)" +args = ["{SimpleBridge}", "{initialSupply}"] + +# Spam 1: depositETH - fuzz tx value from 0.001 to 0.01 ETH +[[spam]] +[spam.tx] +kind = "deposit_eth" +to = "{SimpleBridge}" +from_pool = "depositors" +signature = "function depositETH(uint256 destinationChainId) payable" +args = ["{destinationChainId}"] +value = "0.005 eth" +gas_limit = 150000 +fuzz = [ + { value = true, min = "1000000000000000", max = "10000000000000000" }, +] + +# Spam 2: depositERC20 - fuzz amount from 1e15 to 1e18 +[[spam]] +[spam.tx] +kind = "deposit_erc20" +to = "{SimpleBridge}" +from_pool = "depositors" +signature = "function depositERC20(address token, uint256 amount, uint256 destinationChainId)" +args = ["{BridgeToken}", "1000000000000000000", "{destinationChainId}"] +gas_limit = 200000 +fuzz = [ + { param = "amount", min = "1000000000000000", max = "1000000000000000000" }, +] + +# Spam 3: processDeposit - simulate processing with fuzzed depositHash +[[spam]] +[spam.tx] +kind = "process_deposit" +to = "{SimpleBridge}" +from_pool = "processors" +signature = "function processDeposit(bytes32 depositHash, address recipient, uint256 amount)" +args = ["0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000001", "1000000000000000000"] +gas_limit = 120000 +fuzz = [ + { param = "depositHash", min = "0", max = "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" }, +] diff --git a/scenarios/create2Factory.toml b/scenarios/create2Factory.toml new file mode 100644 index 00000000..cd480b28 --- /dev/null +++ b/scenarios/create2Factory.toml @@ -0,0 +1,108 @@ +# ============================================================ +# CREATE2 Factory + ERC-1167 Minimal Proxy Deployment Spam +# ============================================================ +# Source: /tmp/create2factory.sol +# Compiled with: solc --bin --optimize --optimize-runs 200 +# ============================================================ +# +# This scenario exercises contract creation opcodes as the hot path, +# completely different from function calls on existing contracts. +# +# Three spam patterns: +# 1. createClone — deploy ERC-1167 minimal proxies via CREATE2 +# 2. createAndInitialize — deploy + initialize in one tx +# 3. deploy — full SimpleImplementation deployment via CREATE2 +# +# Each fuzz salt across the full bytes32 range so every tx creates +# a unique contract (CREATE2 addresses are deterministic from salt). + +[env] +# Pre-defined salts for setup verification +salt_one = "0x0000000000000000000000000000000000000000000000000000000000000001" +salt_two = "0x0000000000000000000000000000000000000000000000000000000000000002" +salt_three = "0x0000000000000000000000000000000000000000000000000000000000000003" + + +### Deploy contracts + +# Deploy the implementation contract (the template to be cloned) +[[create]] +name = "SimpleImplementation" +# source: /tmp/create2factory.sol +# compiled with: solc --bin --optimize --optimize-runs 200 +bytecode = "0x6080604052348015600e575f80fd5b506102368061001c5f395ff3fe608060405234801561000f575f80fd5b5060043610610060575f3560e01c8063158ef93e1461006457806320965255146100855780633fa4f2451461009757806355241077146100a05780638da5cb5b146100b5578063c4d66de8146100e4575b5f80fd5b5f546100709060ff1681565b60405190151581526020015b60405180910390f35b6001545b60405190815260200161007c565b61008960015481565b6100b36100ae3660046101bc565b6100f7565b005b5f546100cc9061010090046001600160a01b031681565b6040516001600160a01b03909116815260200161007c565b6100b36100f23660046101d3565b61014b565b5f5461010090046001600160a01b031633146101465760405162461bcd60e51b81526020600482015260096024820152683737ba1037bbb732b960b91b60448201526064015b60405180910390fd5b600155565b5f5460ff16156101935760405162461bcd60e51b8152602060048201526013602482015272185b1c9958591e481a5b9a5d1a585b1a5e9959606a1b604482015260640161013d565b5f80546001600160a01b03909216610100026001600160a81b0319909216919091176001179055565b5f602082840312156101cc575f80fd5b5035919050565b5f602082840312156101e3575f80fd5b81356001600160a01b03811681146101f9575f80fd5b939250505056fea2646970667358221220812c31ae6bafb3e1104476bfa8056e222967e20b601b30edcb076d6ff934021064736f6c634300081a0033" + +# Deploy CloneFactory with the implementation address +[[create]] +name = "CloneFactory" +signature = "(address implementation_)" +args = ["{SimpleImplementation}"] +bytecode = "0x60a0604052348015600e575f80fd5b5060405161047d38038061047d833981016040819052602b91603b565b6001600160a01b03166080526066565b5f60208284031215604a575f80fd5b81516001600160a01b0381168114605f575f80fd5b9392505050565b6080516103f261008b5f395f8181608e0152818161015a015261025501526103f25ff3fe608060405234801561000f575f80fd5b5060043610610055575f3560e01c8063106c3cf1146100595780635c60da1b146100895780639529b922146100b05780639b1a01cc146100c65780639c76b654146100d9575b5f80fd5b61006c6100673660046102f6565b6100ec565b6040516001600160a01b0390911681526020015b60405180910390f35b61006c7f000000000000000000000000000000000000000000000000000000000000000081565b6100b85f5481565b604051908152602001610080565b61006c6100d436600461032f565b610156565b61006c6100e736600461032f565b610251565b5f6100f683610156565b60405163189acdbd60e31b81526001600160a01b0384811660048301529192509082169063c4d66de8906024015f604051808303815f87803b15801561013a575f80fd5b505af115801561014c573d5f803e3d5ffd5b5050505092915050565b5f807f000000000000000000000000000000000000000000000000000000000000000090505f8160405160200161018d9190610346565b6040516020818303038152906040529050838151602083015ff592506001600160a01b0383166101f45760405162461bcd60e51b815260206004820152600e60248201526d18dc99585d194c8819985a5b195960921b604482015260640160405180910390fd5b5f8054908061020283610398565b9190505550826001600160a01b03167f2550d28d8984f456ae812b752ffee2677a2ddccfde0e560e7d8e68b6f8a7401e8560405161024291815260200190565b60405180910390a25050919050565b5f807f000000000000000000000000000000000000000000000000000000000000000090505f816040516020016102889190610346565b60408051808303601f1901815282825280516020918201206001600160f01b0319828501523060601b6bffffffffffffffffffffffff191660218501526035840197909752605580840197909752815180840390970187526075909201905284519401939093209392505050565b5f8060408385031215610307575f80fd5b8235915060208301356001600160a01b0381168114610324575f80fd5b809150509250929050565b5f6020828403121561033f575f80fd5b5035919050565b733d602d80600a3d3981f3363d3d373d3d3d363d7360601b815260609190911b6bffffffffffffffffffffffff191660148201526e5af43d82803e903d91602b57fd5bf360881b602882015260370190565b5f600182016103b557634e487b7160e01b5f52601160045260245ffd5b506001019056fea26469706673582212208395c069aa79bc272c5e57f0dc84d4b9ffd734e08d437222474343657eb09d3364736f6c634300081a0033" + +# Deploy FullDeployFactory for comparison (deploys full contracts, not clones) +[[create]] +name = "FullDeployFactory" +bytecode = "0x6080604052348015600e575f80fd5b506103d98061001c5f395ff3fe608060405234801561000f575f80fd5b5060043610610034575f3560e01c8063091ed157146100385780632b85ba3814610053575b5f80fd5b6100405f5481565b6040519081526020015b60405180910390f35b610066610061366004610116565b61007e565b6040516001600160a01b03909116815260200161004a565b5f808260405161008d90610109565b8190604051809103905ff59050801580156100aa573d5f803e3d5ffd5b505f8054919250806100bb8361012d565b9190505550806001600160a01b03167f77f4d42b4d9aa2e4d25565ed7ccaec28016a7800a41b2061eabeb63e54c21522846040516100fb91815260200190565b60405180910390a292915050565b6102528061015283390190565b5f60208284031215610126575f80fd5b5035919050565b5f6001820161014a57634e487b7160e01b5f52601160045260245ffd5b506001019056fe6080604052348015600e575f80fd5b506102368061001c5f395ff3fe608060405234801561000f575f80fd5b5060043610610060575f3560e01c8063158ef93e1461006457806320965255146100855780633fa4f2451461009757806355241077146100a05780638da5cb5b146100b5578063c4d66de8146100e4575b5f80fd5b5f546100709060ff1681565b60405190151581526020015b60405180910390f35b6001545b60405190815260200161007c565b61008960015481565b6100b36100ae3660046101bc565b6100f7565b005b5f546100cc9061010090046001600160a01b031681565b6040516001600160a01b03909116815260200161007c565b6100b36100f23660046101d3565b61014b565b5f5461010090046001600160a01b031633146101465760405162461bcd60e51b81526020600482015260096024820152683737ba1037bbb732b960b91b60448201526064015b60405180910390fd5b600155565b5f5460ff16156101935760405162461bcd60e51b8152602060048201526013602482015272185b1c9958591e481a5b9a5d1a585b1a5e9959606a1b604482015260640161013d565b5f80546001600160a01b03909216610100026001600160a81b0319909216919091176001179055565b5f602082840312156101cc575f80fd5b5035919050565b5f602082840312156101e3575f80fd5b81356001600160a01b03811681146101f9575f80fd5b939250505056fea2646970667358221220812c31ae6bafb3e1104476bfa8056e222967e20b601b30edcb076d6ff934021064736f6c634300081a0033a2646970667358221220c01653a83cc869d2951b21f38aaaf968a6511a561af0426fede7431eb04e9add64736f6c634300081a0033" + + +### Setup: create a few initial clones to verify the factory works + +[[setup]] +kind = "setup_clone_1" +to = "{CloneFactory}" +from_pool = "admin" +signature = "createClone(bytes32 salt) returns (address)" +args = ["{salt_one}"] + +[[setup]] +kind = "setup_clone_2" +to = "{CloneFactory}" +from_pool = "admin" +signature = "createClone(bytes32 salt) returns (address)" +args = ["{salt_two}"] + +[[setup]] +kind = "setup_clone_3" +to = "{CloneFactory}" +from_pool = "admin" +signature = "createAndInitialize(bytes32 salt, address owner) returns (address)" +args = ["{salt_three}", "{_sender}"] + + +### Spam patterns + +# Spam 1: Deploy minimal proxy clones via CREATE2 (cheapest creation path) +# Each tx deploys a new ERC-1167 proxy; fuzz salt so every address is unique +[[spam]] +[spam.tx] +kind = "create_clone" +to = "{CloneFactory}" +from_pool = "clone_deployers" +signature = "createClone(bytes32 salt) returns (address)" +args = ["{salt_one}"] +gas_limit = 150000 +fuzz = [{ param = "salt", min = "0x0000000000000000000000000000000000000000000000000000000100000000", max = "0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff" }] + +# Spam 2: Deploy + initialize in one tx (proxy creation + storage writes) +# Passes {_sender} as owner so each clone is owned by its deployer +[[spam]] +[spam.tx] +kind = "create_and_init" +to = "{CloneFactory}" +from_pool = "init_deployers" +signature = "createAndInitialize(bytes32 salt, address owner) returns (address)" +args = ["{salt_one}", "{_sender}"] +gas_limit = 200000 +fuzz = [{ param = "salt", min = "0x0000000000000000000000000000000100000000000000000000000000000000", max = "0x000000000000000000000000000000010000000000000000ffffffffffffffff" }] + +# Spam 3: Full contract deployment via CREATE2 (most expensive — full initcode) +# Deploys a complete SimpleImplementation, not a minimal proxy +[[spam]] +[spam.tx] +kind = "full_deploy" +to = "{FullDeployFactory}" +from_pool = "full_deployers" +signature = "deploy(bytes32 salt) returns (address)" +args = ["{salt_one}"] +gas_limit = 300000 +fuzz = [{ param = "salt", min = "0x0000000000000000000000000000000200000000000000000000000000000000", max = "0x00000000000000000000000000000002ffffffffffffffffffffffffffffffff" }] diff --git a/scenarios/diamondProxy.toml b/scenarios/diamondProxy.toml new file mode 100644 index 00000000..e5a87bce --- /dev/null +++ b/scenarios/diamondProxy.toml @@ -0,0 +1,108 @@ +# ============================================================ +# Diamond Proxy (EIP-2535) - Delegatecall Dispatch Benchmark +# ============================================================ +# Tests the delegatecall dispatch pattern: every function call +# goes through a selector lookup + delegatecall in the Diamond +# fallback, adding ~2-5k gas overhead per call. +# +# Source: /tmp/diamond.sol (Diamond, CounterFacet, TokenFacet, StorageFacet) +# Compiled with: solc --bin --optimize --optimize-runs 200 +# ============================================================ + +[env] +mintAmount = "1000000000000000000000000" + +### Deploy contracts + +[[create]] +name = "Diamond" +bytecode = "0x6080604052348015600e575f80fd5b505f60208190527f895ab0585cf72fd183be95f333cf4c800f4e943d61c45ea9bc9ddbae5b7507fe80546001600160a01b03199081163090811790925563096ce8cd60e21b9092527f79a872e537dec3d6e4e454a4855f7397b3d5844c25e5001c6833385b1368de6f805490921617905561046f8061008c5f395ff3fe608060405260043610610037575f3560e01c806325b3a334146100d15780635547dad6146100f0578063ae7473ac1461010f5761003e565b3661003e57005b5f80356001600160e01b0319168152602081905260409020546001600160a01b0316806100b15760405162461bcd60e51b815260206004820152601b60248201527f4469616d6f6e643a2073656c6563746f72206e6f7420666f756e640000000000604482015260640160405180910390fd5b365f80375f80365f845af43d5f803e8080156100cb573d5ff35b3d5ffd5b005b3480156100dc575f80fd5b506100cf6100eb366004610303565b61015f565b3480156100fb575f80fd5b506100cf61010a366004610342565b6101ff565b34801561011a575f80fd5b506101436101293660046103ba565b5f602081905290815260409020546001600160a01b031681565b6040516001600160a01b03909116815260200160405180910390f35b5f5b818110156101c1575f8084848481811061017d5761017d6103da565b905060200201602081019061019291906103ba565b6001600160e01b031916815260208101919091526040015f2080546001600160a01b0319169055600101610161565b507f8676315788709cb33520f39c525fe221fcb6211f8a8e9b083d0da804d6ac26bb82826040516101f39291906103ee565b60405180910390a15050565b5f5b8181101561027257835f8085858581811061021e5761021e6103da565b905060200201602081019061023391906103ba565b6001600160e01b031916815260208101919091526040015f2080546001600160a01b0319166001600160a01b0392909216919091179055600101610201565b50826001600160a01b03167fca14aa63fbdd3798d76f3340b1fa4c2401c80a3cabbe92633daf76fa31a89d4683836040516102ae9291906103ee565b60405180910390a2505050565b5f8083601f8401126102cb575f80fd5b50813567ffffffffffffffff8111156102e2575f80fd5b6020830191508360208260051b85010111156102fc575f80fd5b9250929050565b5f8060208385031215610314575f80fd5b823567ffffffffffffffff81111561032a575f80fd5b610336858286016102bb565b90969095509350505050565b5f805f60408486031215610354575f80fd5b83356001600160a01b038116811461036a575f80fd5b9250602084013567ffffffffffffffff811115610385575f80fd5b610391868287016102bb565b9497909650939450505050565b80356001600160e01b0319811681146103b5575f80fd5b919050565b5f602082840312156103ca575f80fd5b6103d38261039e565b9392505050565b634e487b7160e01b5f52603260045260245ffd5b602080825281018290525f8360408301825b8581101561042f576001600160e01b031961041a8461039e565b16825260209283019290910190600101610400565b509594505050505056fea2646970667358221220225c24f50bfe4d1ce85e2868a639f0f99498ed68755286f741fa4d154149389b64736f6c634300081a0033" + +[[create]] +name = "CounterFacet" +bytecode = "0x6080604052348015600e575f80fd5b506101148061001c5f395ff3fe6080604052348015600e575f80fd5b50600436106030575f3560e01c8063a87d942c146034578063d09de08a146074575b5f80fd5b7fb7b015d605ece0e8fe533fe842b448ce2b6465e6d573f424dd3872fbf18242565f90815233602052604090205460405190815260200160405180910390f35b607a607c565b005b7fb7b015d605ece0e8fe533fe842b448ce2b6465e6d573f424dd3872fbf18242565f9081523360205260409020805460b460018260ba565b90915550565b8082018082111560d857634e487b7160e01b5f52601160045260245ffd5b9291505056fea26469706673582212200cfb4ace4a8dea23cb81fb5facd6d06a4a32a415dda774671b08c32f0a32545864736f6c634300081a0033" + +[[create]] +name = "TokenFacet" +bytecode = "0x6080604052348015600e575f80fd5b506102378061001c5f395ff3fe608060405234801561000f575f80fd5b506004361061003f575f3560e01c806340c10f191461004357806370a08231146100b0578063a9059cbb14610100575b5f80fd5b6100ae6100513660046101b9565b5f9182527fc0abc52de3d4e570867f700eb5dfe2c039750b7f48720ee0d6152f3aa867637560205260409091207fc0abc52de3d4e570867f700eb5dfe2c039750b7f48720ee0d6152f3aa867637480548301905580549091019055565b005b6100ee6100be3660046101e1565b5f9081527fc0abc52de3d4e570867f700eb5dfe2c039750b7f48720ee0d6152f3aa8676375602052604090205490565b60405190815260200160405180910390f35b6100ae61010e3660046101b9565b335f9081527fc0abc52de3d4e570867f700eb5dfe2c039750b7f48720ee0d6152f3aa86763756020526040808220848352912081548381101561018e5760405162461bcd60e51b8152602060048201526014602482015273696e73756666696369656e742062616c616e636560601b604482015260640160405180910390fd5b8390039091558054909101905550565b80356001600160a01b03811681146101b4575f80fd5b919050565b5f80604083850312156101ca575f80fd5b6101d38361019e565b946020939093013593505050565b5f602082840312156101f1575f80fd5b6101fa8261019e565b939250505056fea2646970667358221220f75063f8d86dcbb4d9b18961b1988ce8d9f30483ec176918a089bd60e755389164736f6c634300081a0033" + +[[create]] +name = "StorageFacet" +bytecode = "0x6080604052348015600e575f80fd5b506101858061001c5f395ff3fe608060405234801561000f575f80fd5b5060043610610034575f3560e01c806336c217f8146100385780639718cb5a1461005d575b5f80fd5b61004b610046366004610113565b610072565b60405190815260200160405180910390f35b61007061006b366004610113565b6100c9565b005b5f805b828110156100c3577f5268883d862bac3955457cee4337600999ea29b35dc8eb0a4db02d83ba55e3935f90815260208290526040902080546100b7818561012a565b93505050600101610075565b50919050565b5f5b8181101561010f577f5268883d862bac3955457cee4337600999ea29b35dc8eb0a4db02d83ba55e3935f9081526020829052604090206001909101908190556100cb565b5050565b5f60208284031215610123575f80fd5b5035919050565b8082018082111561014957634e487b7160e01b5f52601160045260245ffd5b9291505056fea264697066735822122000d4d91d4d7ba9d0c278143306644e9166da9a2eaff036dd24c4c82eeffd573d64736f6c634300081a0033" + +### Setup: register CounterFacet selectors on Diamond + +[[setup]] +kind = "register_counter_facet" +to = "{Diamond}" +signature = "addFacet(address facet, bytes4[] selectors)" +args = ["{CounterFacet}", "[0xd09de08a,0xa87d942c]"] + +### Setup: register TokenFacet selectors on Diamond + +[[setup]] +kind = "register_token_facet" +to = "{Diamond}" +signature = "addFacet(address facet, bytes4[] selectors)" +args = ["{TokenFacet}", "[0x40c10f19,0xa9059cbb,0x70a08231]"] + +### Setup: register StorageFacet selectors on Diamond + +[[setup]] +kind = "register_storage_facet" +to = "{Diamond}" +signature = "addFacet(address facet, bytes4[] selectors)" +args = ["{StorageFacet}", "[0x9718cb5a,0x36c217f8]"] + +### Setup: mint initial tokens to all spammer accounts via Diamond (routed to TokenFacet) + +[[setup]] +kind = "spammer_mint_tokens" +to = "{Diamond}" +from_pool = "spammer" +for_all_accounts = true +signature = "mint(address to, uint256 amount)" +args = ["{_sender}", "{mintAmount}"] + +### Spam patterns (all calls go to Diamond, dispatched via delegatecall) + +# 1. Increment counter — routed to CounterFacet via delegatecall +[[spam]] +[spam.tx] +kind = "increment" +to = "{Diamond}" +from_pool = "spammer" +signature = "increment()" +args = [] + +# 2. Transfer tokens — routed to TokenFacet via delegatecall +[[spam]] +[spam.tx] +kind = "transfer" +to = "{Diamond}" +from_pool = "spammer" +signature = "transfer(address to, uint256 amount)" +args = ["{_sender}", "1000000000000000000"] +gas_limit = 200000 +fuzz = [{ param = "amount", min = "100000000000000000", max = "10000000000000000000" }] + +# 3. Write many storage slots — routed to StorageFacet via delegatecall (stress test) +[[spam]] +[spam.tx] +kind = "write_many" +to = "{Diamond}" +from_pool = "spammer" +signature = "writeMany(uint256 count)" +args = ["25"] +gas_limit = 5000000 +fuzz = [{ param = "count", min = "5", max = "50" }] + +# 4. Mint tokens — routed to TokenFacet via delegatecall +[[spam]] +[spam.tx] +kind = "mint" +to = "{Diamond}" +from_pool = "spammer" +signature = "mint(address to, uint256 amount)" +args = ["{_sender}", "500000000000000000000"] +fuzz = [{ param = "amount", min = "100000000000000000000", max = "1000000000000000000000" }] diff --git a/scenarios/dutchAuction.toml b/scenarios/dutchAuction.toml new file mode 100644 index 00000000..580de137 --- /dev/null +++ b/scenarios/dutchAuction.toml @@ -0,0 +1,37 @@ +# ============================================================ +# Dutch Auction - Decreasing Price Auction Stress Test +# ============================================================ +# Source: /tmp/auction.sol (Solidity 0.8.26, optimized with 200 runs) +# Gas profile: ~60-80k per bid (timestamp read, price calc with division, +# counter increments, ETH refunds via low-level call) +# ============================================================ + +[env] +# 1 ETH start price +startPrice = "1000000000000000000" +# 0.1 ETH end price +endPrice = "100000000000000000" +# 1 hour duration +duration = "3600" + +# Deploy DutchAuction with constructor(startPrice, endPrice, duration) +[[create]] +name = "DutchAuction" +signature = "(uint256 startPrice_, uint256 endPrice_, uint256 duration_)" +args = ["{startPrice}", "{endPrice}", "{duration}"] +bytecode = "0x608060405234801561000f575f80fd5b5060405161065338038061065383398101604081905261002e916100f7565b8183116100825760405162461bcd60e51b815260206004820152601f60248201527f73746172745072696365206d7573742065786365656420656e6450726963650060448201526064015b60405180910390fd5b5f81116100d15760405162461bcd60e51b815260206004820152601960248201527f6475726174696f6e206d75737420626520706f736974697665000000000000006044820152606401610079565b5f80546001600160a01b0319163317905542600155600292909255600355600455610122565b5f805f60608486031215610109575f80fd5b5050815160208301516040909301519094929350919050565b6105248061012f5f395ff3fe60806040526004361061008f575f3560e01c80639106d7ba116100575780639106d7ba14610124578063b868723e14610139578063bfb89d971461014e578063eb91d37e14610179578063f1a9af891461018d575f80fd5b80630fb5a6b4146100935780631998aeef146100bb5780633ccfd60b146100c557806378e97925146100d95780638da5cb5b146100ee575b5f80fd5b34801561009e575f80fd5b506100a860045481565b6040519081526020015b60405180910390f35b6100c36101a2565b005b3480156100d0575f80fd5b506100c3610309565b3480156100e4575f80fd5b506100a860015481565b3480156100f9575f80fd5b505f5461010c906001600160a01b031681565b6040516001600160a01b0390911681526020016100b2565b34801561012f575f80fd5b506100a860055481565b348015610144575f80fd5b506100a860035481565b348015610159575f80fd5b506100a8610168366004610446565b60066020525f908152604090205481565b348015610184575f80fd5b506100a86103e3565b348015610198575f80fd5b506100a860025481565b5f6101ab6103e3565b9050803410156101f95760405162461bcd60e51b8152602060048201526014602482015273125b9cdd59999a58da595b9d081c185e5b595b9d60621b60448201526064015b60405180910390fd5b60058054905f61020883610487565b9091555050600554335f90815260066020526040812080549161022a83610487565b9091555050604080518381526020810183905233917f1452773cf753d0d7c71ed9990f7c7e2bdde4a2d08d187b3647953877e400488d910160405180910390a25f610275833461049f565b90508015610304576040515f90339083908381818185875af1925050503d805f81146102bc576040519150601f19603f3d011682016040523d82523d5f602084013e6102c1565b606091505b50509050806103025760405162461bcd60e51b815260206004820152600d60248201526c1499599d5b990819985a5b1959609a1b60448201526064016101f0565b505b505050565b5f546001600160a01b0316331461034e5760405162461bcd60e51b81526020600482015260096024820152682737ba1037bbb732b960b91b60448201526064016101f0565b5f80546040516001600160a01b039091169047908381818185875af1925050503d805f8114610398576040519150601f19603f3d011682016040523d82523d5f602084013e61039d565b606091505b50509050806103e05760405162461bcd60e51b815260206004820152600f60248201526e15da5d1a191c985dc819985a5b1959608a1b60448201526064016101f0565b50565b5f80600154426103f3919061049f565b9050600454811061040657505060035490565b5f6004548260035460025461041b919061049f565b61042591906104b8565b61042f91906104cf565b90508060025461043f919061049f565b9250505090565b5f60208284031215610456575f80fd5b81356001600160a01b038116811461046c575f80fd5b9392505050565b634e487b7160e01b5f52601160045260245ffd5b5f6001820161049857610498610473565b5060010190565b818103818111156104b2576104b2610473565b92915050565b80820281158282048414176104b2576104b2610473565b5f826104e957634e487b7160e01b5f52601260045260245ffd5b50049056fea2646970667358221220483eeabfcd8b4372ec36542a523f6ecbf852c2207137e878acecc86a82a246af64736f6c634300081a0033" + +# Spam: bid on the auction with fuzzed ETH value +# Value is fuzzed between 0.1 ETH and 1 ETH to ensure bids succeed +# even as the price decreases over the auction duration. +# Excess ETH is refunded by the contract, exercising the refund gas pattern. +[[spam]] +[spam.tx] +kind = "bid" +to = "{DutchAuction}" +from_pool = "bidders" +signature = "function bid() external payable" +args = [] +value = "1000000000000000000" +gas_limit = 150000 +fuzz = [{ value = true, min = "100000000000000000", max = "1000000000000000000" }] diff --git a/scenarios/erc1155.toml b/scenarios/erc1155.toml new file mode 100644 index 00000000..89235d79 --- /dev/null +++ b/scenarios/erc1155.toml @@ -0,0 +1,131 @@ +# ERC1155 Multi-Token Benchmark Scenario +# source: /tmp/erc1155.sol (self-contained MinimalERC1155, solidity 0.8.26) +# compiled: solc --bin --optimize --optimize-runs 200 +# +# Gas profile (approximate): +# - mint: ~51k gas (cold) / ~34k gas (warm) +# - safeTransferFrom: ~52k gas (warm) +# - safeBatchTransferFrom: ~30k + ~26k per token ID + +[env] +mintAmount = "1000000" + +### Deploy contract + +[[create]] +name = "ERC1155" +bytecode = "0x6080604052348015600e575f80fd5b50610ab38061001c5f395ff3fe608060405234801561000f575f80fd5b506004361061005f575f3560e01c8062fdd58e14610063578063156e29f6146100895780632eb2c2d61461009e578063a22cb465146100b1578063e985e9c5146100c4578063f242432a146100e7575b5f80fd5b6100766100713660046106e8565b6100fa565b6040519081526020015b60405180910390f35b61009c610097366004610710565b610121565b005b61009c6100ac3660046107c6565b6101fd565b61009c6100bf366004610885565b61046f565b6100d76100d23660046108be565b61053d565b6040519015158152602001610080565b61009c6100f53660046108ef565b61056a565b5f818152602081815260408083206001600160a01b03861684529091529020545b92915050565b6001600160a01b03831661017c5760405162461bcd60e51b815260206004820152601d60248201527f455243313135353a206d696e7420746f207a65726f206164647265737300000060448201526064015b60405180910390fd5b5f828152602081815260408083206001600160a01b0387168452909152812080548392906101ab908490610962565b909155505060408051838152602081018390526001600160a01b038516915f9133917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a4505050565b8483146102585760405162461bcd60e51b8152602060048201526024808201527f455243313135353a206964732f616d6f756e7473206c656e677468206d69736d6044820152630c2e8c6d60e31b6064820152608401610173565b6001600160a01b03871661027e5760405162461bcd60e51b815260040161017390610981565b6001600160a01b03881633148061029a575061029a883361053d565b6102b65760405162461bcd60e51b8152600401610173906109c2565b5f5b85811015610409575f8787838181106102d3576102d3610a08565b9050602002013590505f8686848181106102ef576102ef610a08565b9050602002013590505f805f8481526020019081526020015f205f8d6001600160a01b03166001600160a01b031681526020019081526020015f205490508181101561037d5760405162461bcd60e51b815260206004820152601d60248201527f455243313135353a20696e73756666696369656e742062616c616e63650000006044820152606401610173565b8181035f808581526020019081526020015f205f8e6001600160a01b03166001600160a01b031681526020019081526020015f2081905550815f808581526020019081526020015f205f8d6001600160a01b03166001600160a01b031681526020019081526020015f205f8282546103f59190610962565b9091555050600190930192506102b8915050565b50866001600160a01b0316886001600160a01b0316336001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8989898960405161045d9493929190610a4c565b60405180910390a45050505050505050565b336001600160a01b038316036104d25760405162461bcd60e51b815260206004820152602260248201527f455243313135353a2073657474696e6720617070726f76616c20666f72207365604482015261363360f11b6064820152608401610173565b335f8181526001602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b6001600160a01b039182165f90815260016020908152604080832093909416825291909152205460ff1690565b6001600160a01b0385166105905760405162461bcd60e51b815260040161017390610981565b6001600160a01b0386163314806105ac57506105ac863361053d565b6105c85760405162461bcd60e51b8152600401610173906109c2565b5f848152602081815260408083206001600160a01b038a168452909152902054838110156106385760405162461bcd60e51b815260206004820152601d60248201527f455243313135353a20696e73756666696369656e742062616c616e63650000006044820152606401610173565b5f858152602081815260408083206001600160a01b038b8116855292528083208785039055908816825281208054869290610674908490610962565b909155505060408051868152602081018690526001600160a01b0380891692908a169133917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a450505050505050565b80356001600160a01b03811681146106e3575f80fd5b919050565b5f80604083850312156106f9575f80fd5b610702836106cd565b946020939093013593505050565b5f805f60608486031215610722575f80fd5b61072b846106cd565b95602085013595506040909401359392505050565b5f8083601f840112610750575f80fd5b50813567ffffffffffffffff811115610767575f80fd5b6020830191508360208260051b8501011115610781575f80fd5b9250929050565b5f8083601f840112610798575f80fd5b50813567ffffffffffffffff8111156107af575f80fd5b602083019150836020828501011115610781575f80fd5b5f805f805f805f8060a0898b0312156107dd575f80fd5b6107e6896106cd565b97506107f460208a016106cd565b9650604089013567ffffffffffffffff81111561080f575f80fd5b61081b8b828c01610740565b909750955050606089013567ffffffffffffffff81111561083a575f80fd5b6108468b828c01610740565b909550935050608089013567ffffffffffffffff811115610865575f80fd5b6108718b828c01610788565b999c989b5096995094979396929594505050565b5f8060408385031215610896575f80fd5b61089f836106cd565b9150602083013580151581146108b3575f80fd5b809150509250929050565b5f80604083850312156108cf575f80fd5b6108d8836106cd565b91506108e6602084016106cd565b90509250929050565b5f805f805f8060a08789031215610904575f80fd5b61090d876106cd565b955061091b602088016106cd565b94506040870135935060608701359250608087013567ffffffffffffffff811115610944575f80fd5b61095089828a01610788565b979a9699509497509295939492505050565b8082018082111561011b57634e487b7160e01b5f52601160045260245ffd5b60208082526021908201527f455243313135353a207472616e7366657220746f207a65726f206164647265736040820152607360f81b606082015260800190565b60208082526026908201527f455243313135353a2063616c6c6572206e6f74206f776e6572206e6f722061706040820152651c1c9bdd995960d21b606082015260800190565b634e487b7160e01b5f52603260045260245ffd5b8183525f6001600160fb1b03831115610a33575f80fd5b8260051b80836020870137939093016020019392505050565b604081525f610a5f604083018688610a1c565b8281036020840152610a72818587610a1c565b97965050505050505056fea26469706673582212200d36711f67833667355f2e122f8d60cfab9ed955fa5570b8dd200a21fc83acea64736f6c634300081a0033" + +### Setup: mint initial token balances + +# Mint token IDs 1-5 (1,000,000 each) to admin +[[setup]] +kind = "mint_admin_token_1" +to = "{ERC1155}" +signature = "mint(address to, uint256 id, uint256 amount)" +args = ["{_sender}", "1", "{mintAmount}"] + +[[setup]] +kind = "mint_admin_token_2" +to = "{ERC1155}" +signature = "mint(address to, uint256 id, uint256 amount)" +args = ["{_sender}", "2", "{mintAmount}"] + +[[setup]] +kind = "mint_admin_token_3" +to = "{ERC1155}" +signature = "mint(address to, uint256 id, uint256 amount)" +args = ["{_sender}", "3", "{mintAmount}"] + +[[setup]] +kind = "mint_admin_token_4" +to = "{ERC1155}" +signature = "mint(address to, uint256 id, uint256 amount)" +args = ["{_sender}", "4", "{mintAmount}"] + +[[setup]] +kind = "mint_admin_token_5" +to = "{ERC1155}" +signature = "mint(address to, uint256 id, uint256 amount)" +args = ["{_sender}", "5", "{mintAmount}"] + +# Mint token IDs 1-5 to all spammer accounts +[[setup]] +kind = "mint_spammers_token_1" +to = "{ERC1155}" +from_pool = "spammers" +for_all_accounts = true +signature = "mint(address to, uint256 id, uint256 amount)" +args = ["{_sender}", "1", "{mintAmount}"] + +[[setup]] +kind = "mint_spammers_token_2" +to = "{ERC1155}" +from_pool = "spammers" +for_all_accounts = true +signature = "mint(address to, uint256 id, uint256 amount)" +args = ["{_sender}", "2", "{mintAmount}"] + +[[setup]] +kind = "mint_spammers_token_3" +to = "{ERC1155}" +from_pool = "spammers" +for_all_accounts = true +signature = "mint(address to, uint256 id, uint256 amount)" +args = ["{_sender}", "3", "{mintAmount}"] + +[[setup]] +kind = "mint_spammers_token_4" +to = "{ERC1155}" +from_pool = "spammers" +for_all_accounts = true +signature = "mint(address to, uint256 id, uint256 amount)" +args = ["{_sender}", "4", "{mintAmount}"] + +[[setup]] +kind = "mint_spammers_token_5" +to = "{ERC1155}" +from_pool = "spammers" +for_all_accounts = true +signature = "mint(address to, uint256 id, uint256 amount)" +args = ["{_sender}", "5", "{mintAmount}"] + +### Spam patterns + +# 1. Single mint - mint new tokens with fuzzed ID and amount +[[spam]] +[spam.tx] +kind = "erc1155_mint" +to = "{ERC1155}" +from_pool = "spammers" +signature = "mint(address to, uint256 id, uint256 amount)" +args = ["{_sender}", "100", "1000"] +gas_limit = 80000 +fuzz = [ + { param = "id", min = "100", max = "10000" }, + { param = "amount", min = "1", max = "100000" }, +] + +# 2. Single transfer - safeTransferFrom to self, fuzz amount +[[spam]] +[spam.tx] +kind = "erc1155_single_transfer" +to = "{ERC1155}" +from_pool = "spammers" +signature = "safeTransferFrom(address from, address to, uint256 id, uint256 amount, bytes data)" +args = ["{_sender}", "{_sender}", "1", "1", "0x"] +gas_limit = 80000 +fuzz = [ + { param = "id", min = "1", max = "5" }, + { param = "amount", min = "1", max = "10" }, +] + +# 3. Batch transfer - transfer multiple token IDs at once to self +[[spam]] +[spam.tx] +kind = "erc1155_batch_transfer" +to = "{ERC1155}" +from_pool = "spammers" +signature = "safeBatchTransferFrom(address from, address to, uint256[] ids, uint256[] amounts, bytes data)" +args = ["{_sender}", "{_sender}", "[1,2,3]", "[1,1,1]", "0x"] +gas_limit = 200000 diff --git a/scenarios/erc4337.toml b/scenarios/erc4337.toml new file mode 100644 index 00000000..bd87e7df --- /dev/null +++ b/scenarios/erc4337.toml @@ -0,0 +1,72 @@ +# ============================================================ +# ERC-4337 Account Abstraction - Stress Test +# ============================================================ +# Source: /tmp/erc4337.sol (Solidity 0.8.26, optimized with 200 runs) +# Gas profile: two-loop validate-then-execute pattern (~2% mainnet gas), +# nested low-level calls, signature verification, +# nonce tracking, deposit accounting, event emissions +# Pattern: UserOpHelper constructs UserOperations and submits +# them through SimpleEntryPoint.handleOps, which first +# validates all ops (loop 1) then executes all (loop 2). +# Each UserOp calls SimpleAccount.execute -> SimpleCounter. +# ============================================================ + +[env] +depositAmount = "10000000000000000000" +fundAmount = "5000000000000000000" +incrementCalldata = "0xd09de08a" + +### Deploy contracts + +# 1. Deploy SimpleEntryPoint +[[create]] +name = "SimpleEntryPoint" +bytecode = "0x6080604052348015600e575f80fd5b50610b7f8061001c5f395ff3fe608060405260043610610057575f3560e01c806370a08231146100625780637ecebe00146100a85780638c321383146100d3578063b760faf9146100f2578063d6ef564e14610107578063fc7e286d14610126575f80fd5b3661005e57005b5f80fd5b34801561006d575f80fd5b5061009661007c366004610826565b6001600160a01b03165f9081526001602052604090205490565b60405190815260200160405180910390f35b3480156100b3575f80fd5b506100966100c2366004610826565b5f6020819052908152604090205481565b3480156100de575f80fd5b506100966100ed366004610848565b610151565b610105610100366004610826565b610204565b005b348015610112575f80fd5b50610105610121366004610880565b610233565b348015610131575f80fd5b50610096610140366004610826565b60016020525f908152604090205481565b5f61015f6020830183610826565b60208301356101716040850185610902565b60405161017f92919061094c565b604080519182900382206001600160a01b0390941660208301528101919091526060808201929092529083013560808083019190915283013560a08083019190915283013560c08083019190915283013560e0820152466101008201523061012082015261014001604051602081830303815290604052805190602001209050919050565b6001600160a01b0381165f908152600160205260408120805434929061022b90849061096f565b909155505050565b815f8167ffffffffffffffff81111561024e5761024e610988565b604051908082528060200260200182016040528015610277578160200160208202803683370190505b5090505f5b828110156105cf57368686838181106102975761029761099c565b90506020028101906102a991906109b0565b90505f6102b582610151565b9050808484815181106102ca576102ca61099c565b6020026020010181815250505f80835f0160208101906102ea9190610826565b6001600160a01b03166001600160a01b031681526020019081526020015f20548260200135146103555760405162461bcd60e51b815260206004820152601160248201527045503a20696e76616c6964206e6f6e636560781b60448201526064015b60405180910390fd5b6103646020830135600161096f565b5f806103736020860186610826565b6001600160a01b0316815260208101919091526040015f908120919091556103a36080840135606085013561096f565b90505f6103b460a0850135836109ce565b90505f6001816103c76020880188610826565b6001600160a01b03166001600160a01b031681526020019081526020015f205490505f828210156103ff576103fc82846109e5565b90505b5f8061040e6020890189610826565b6001600160a01b031688888560405160240161042c93929190610a62565b60408051601f198184030181529181526020820180516001600160e01b0316631f74c08d60e11b179052516104619190610b1c565b5f604051808303815f865af19150503d805f811461049a576040519150601f19603f3d011682016040523d82523d5f602084013e61049f565b606091505b50915091508180156104b357506020815110155b6104f75760405162461bcd60e51b815260206004820152601560248201527411540e881d985b1a59185d1a5bdb8819985a5b1959605a1b604482015260640161034c565b5f8180602001905181019061050c9190610b32565b9050801561055c5760405162461bcd60e51b815260206004820152601960248201527f45503a207369672076616c69646174696f6e206661696c656400000000000000604482015260640161034c565b60015f61056c60208c018c610826565b6001600160a01b03166001600160a01b031681526020019081526020015f205460015f8b5f0160208101906105a19190610826565b6001600160a01b0316815260208101919091526040015f205550506001909701965061027c95505050505050565b505f5b8281101561079857368686838181106105ed576105ed61099c565b90506020028101906105ff91906109b0565b90505f5a90505f6106136020840184610826565b6001600160a01b0316606084013561062e6040860186610902565b60405161063c92919061094c565b5f604051808303815f8787f1925050503d805f8114610676576040519150601f19603f3d011682016040523d82523d5f602084013e61067b565b606091505b505090505f5a61068b90846109e5565b90505f6106983a836109ce565b90508060015f6106ab6020890189610826565b6001600160a01b03166001600160a01b031681526020019081526020015f205410610714578060015f6106e16020890189610826565b6001600160a01b03166001600160a01b031681526020019081526020015f205f82825461070e91906109e5565b90915550505b6107216020860186610826565b6001600160a01b031687878151811061073c5761073c61099c565b60200260200101517e06f0150226cd77c84a83140993df729ea65eba27bf12e10ce9fc05f34200f4858460405161077f9291909115158252602082015260400190565b60405180910390a35050600190930192506105d2915050565b505f471180156107b057506001600160a01b03831615155b15610808575f836001600160a01b0316476040515f6040518083038185875af1925050503d805f81146107fe576040519150601f19603f3d011682016040523d82523d5f602084013e610803565b606091505b505050505b5050505050565b6001600160a01b0381168114610823575f80fd5b50565b5f60208284031215610836575f80fd5b81356108418161080f565b9392505050565b5f60208284031215610858575f80fd5b813567ffffffffffffffff81111561086e575f80fd5b82016101008185031215610841575f80fd5b5f805f60408486031215610892575f80fd5b833567ffffffffffffffff8111156108a8575f80fd5b8401601f810186136108b8575f80fd5b803567ffffffffffffffff8111156108ce575f80fd5b8660208260051b84010111156108e2575f80fd5b6020918201945092508401356108f78161080f565b809150509250925092565b5f808335601e19843603018112610917575f80fd5b83018035915067ffffffffffffffff821115610931575f80fd5b602001915036819003821315610945575f80fd5b9250929050565b818382375f9101908152919050565b634e487b7160e01b5f52601160045260245ffd5b808201808211156109825761098261095b565b92915050565b634e487b7160e01b5f52604160045260245ffd5b634e487b7160e01b5f52603260045260245ffd5b5f823560fe198336030181126109c4575f80fd5b9190910192915050565b80820281158282048414176109825761098261095b565b818103818111156109825761098261095b565b5f808335601e19843603018112610a0d575f80fd5b830160208101925035905067ffffffffffffffff811115610a2c575f80fd5b803603821315610945575f80fd5b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b606081525f8435610a728161080f565b6001600160a01b0316606083015260208501356080830152610a9760408601866109f8565b61010060a0850152610aae61016085018284610a3a565b606088013560c086810191909152608089013560e08088019190915260a08a013561010088015290890135610120870152909250610aef91508701876109f8565b848303605f1901610140860152610b07838284610a3a565b60208601979097525050505060400152919050565b5f82518060208501845e5f920191825250919050565b5f60208284031215610b42575f80fd5b505191905056fea264697066735822122073a8036a12a0a2f1b81a72e9b73d70640d0ba6671fa43e17c134359516c9e84264736f6c634300081a0033" + +# 2. Deploy SimpleCounter +[[create]] +name = "SimpleCounter" +bytecode = "0x6080604052348015600e575f80fd5b5061010a8061001c5f395ff3fe6080604052348015600e575f80fd5b5060043610603a575f3560e01c806303df179c14603e57806306661abd14604f578063d09de08a146068575b5f80fd5b604d6049366004609a565b606e565b005b60565f5481565b60405190815260200160405180910390f35b604d6084565b805f80828254607c919060b0565b909155505050565b60015f808282546093919060b0565b9091555050565b5f6020828403121560a9575f80fd5b5035919050565b8082018082111560ce57634e487b7160e01b5f52601160045260245ffd5b9291505056fea2646970667358221220b305795bd2150ae2a7ec14aa47d57282bf88bb0e56909bb04777b7109751d8af64736f6c634300081a0033" + +# 3. Deploy SimpleAccount (constructor: entryPoint address, owner address) +# Owner is set to the admin sender so signature validation passes +[[create]] +name = "SimpleAccount" +signature = "constructor(address,address)" +args = ["{SimpleEntryPoint}", "{_sender}"] +bytecode = "0x6080604052348015600e575f80fd5b506040516107bb3803806107bb833981016040819052602b916074565b600180546001600160a01b039384166001600160a01b0319918216179091555f805492909316911617905560a0565b80516001600160a01b0381168114606f575f80fd5b919050565b5f80604083850312156084575f80fd5b608b83605a565b9150609760208401605a565b90509250929050565b61070e806100ad5f395ff3fe60806040526004361061004c575f3560e01c806318dfb3c7146100575780633ee9811a146100785780638da5cb5b146100aa578063b0d691fe146100e0578063b61d27f6146100ff575f80fd5b3661005357005b5f80fd5b348015610062575f80fd5b506100766100713660046104cd565b61011e565b005b348015610083575f80fd5b50610097610092366004610539565b6102a2565b6040519081526020015b60405180910390f35b3480156100b5575f80fd5b505f546100c8906001600160a01b031681565b6040516001600160a01b0390911681526020016100a1565b3480156100eb575f80fd5b506001546100c8906001600160a01b031681565b34801561010a575f80fd5b506100766101193660046105a3565b6103b8565b6001546001600160a01b031633146101515760405162461bcd60e51b815260040161014890610626565b60405180910390fd5b8281146101965760405162461bcd60e51b81526020600482015260136024820152720a6827440d8cadccee8d040dad2e6dac2e8c6d606b1b6044820152606401610148565b5f5b8381101561029b575f8585838181106101b3576101b3610652565b90506020020160208101906101c89190610666565b6001600160a01b03168484848181106101e3576101e3610652565b90506020028101906101f59190610686565b6040516102039291906106c9565b5f604051808303815f865af19150503d805f811461023c576040519150601f19603f3d011682016040523d82523d5f602084013e610241565b606091505b50509050806102925760405162461bcd60e51b815260206004820152601a60248201527f53413a20626174636820657865637574696f6e206661696c65640000000000006044820152606401610148565b50600101610198565b5050505050565b6001545f906001600160a01b031633146102ce5760405162461bcd60e51b815260040161014890610626565b5f60146102de60e0870187610686565b905010610344575f806102f460e0880188610686565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f92018290525060149094015193546001600160a01b03948516941693909314955050505050505b821561039e576001546040515f916001600160a01b03169085908381818185875af1925050503d805f8114610394576040519150601f19603f3d011682016040523d82523d5f602084013e610399565b606091505b505050505b806103aa5760016103ac565b5f5b60ff1695945050505050565b6001546001600160a01b031633146103e25760405162461bcd60e51b815260040161014890610626565b5f846001600160a01b03168484846040516103fe9291906106c9565b5f6040518083038185875af1925050503d805f8114610438576040519150601f19603f3d011682016040523d82523d5f602084013e61043d565b606091505b505090508061029b5760405162461bcd60e51b815260206004820152601460248201527314d04e88195e1958dd5d1a5bdb8819985a5b195960621b6044820152606401610148565b5f8083601f840112610495575f80fd5b50813567ffffffffffffffff8111156104ac575f80fd5b6020830191508360208260051b85010111156104c6575f80fd5b9250929050565b5f805f80604085870312156104e0575f80fd5b843567ffffffffffffffff8111156104f6575f80fd5b61050287828801610485565b909550935050602085013567ffffffffffffffff811115610521575f80fd5b61052d87828801610485565b95989497509550505050565b5f805f6060848603121561054b575f80fd5b833567ffffffffffffffff811115610561575f80fd5b84016101008187031215610573575f80fd5b95602085013595506040909401359392505050565b80356001600160a01b038116811461059e575f80fd5b919050565b5f805f80606085870312156105b6575f80fd5b6105bf85610588565b935060208501359250604085013567ffffffffffffffff8111156105e1575f80fd5b8501601f810187136105f1575f80fd5b803567ffffffffffffffff811115610607575f80fd5b876020828401011115610618575f80fd5b949793965060200194505050565b60208082526012908201527114d04e881b9bdd08195b9d1c9e5c1bda5b9d60721b604082015260600190565b634e487b7160e01b5f52603260045260245ffd5b5f60208284031215610676575f80fd5b61067f82610588565b9392505050565b5f808335601e1984360301811261069b575f80fd5b83018035915067ffffffffffffffff8211156106b5575f80fd5b6020019150368190038213156104c6575f80fd5b818382375f910190815291905056fea2646970667358221220673986967921f125e821166f739a9196a0f8ab436744db2cf46d07536726bb8864736f6c634300081a0033" + +# 4. Deploy UserOpHelper (no constructor args) +[[create]] +name = "UserOpHelper" +bytecode = "0x6080604052348015600e575f80fd5b5061063d8061001c5f395ff3fe608060405234801561000f575f80fd5b5060043610610029575f3560e01c80634a69c5e71461002d575b5f80fd5b61004061003b3660046103b9565b610042565b005b5f8585858560405160240161005a9493929190610471565b60408051601f198184030181529190526020810180516001600160e01b0316635b0e93fb60e11b17905290505f6100918989610290565b60408051606086901b6bffffffffffffffffffffffff191660208201528151601481830301815260016034830181815260748401909452939450925f92916054015b61011e6040518061010001604052805f6001600160a01b031681526020015f8152602001606081526020015f81526020015f81526020015f81526020015f8152602001606081525090565b8152602001906001900390816100d35790505090506040518061010001604052808b6001600160a01b0316815260200184815260200185815260200162030d408152602001620186a08152602001600181526020016001815260200183815250815f81518110610190576101906104b8565b60200260200101819052505f8b6001600160a01b031682336040516024016101b99291906104fa565b60408051601f198184030181529181526020820180516001600160e01b0316636b77ab2760e11b179052516101ee91906105da565b5f604051808303815f865af19150503d805f8114610227576040519150601f19603f3d011682016040523d82523d5f602084013e61022c565b606091505b50509050806102825760405162461bcd60e51b815260206004820152601860248201527f48656c7065723a2068616e646c654f7073206661696c6564000000000000000060448201526064015b60405180910390fd5b505050505050505050505050565b6040516001600160a01b0382811660248301525f91829182919086169060440160408051601f198184030181529181526020820180516001600160e01b0316623f675f60e91b179052516102e491906105da565b5f60405180830381855afa9150503d805f811461031c576040519150601f19603f3d011682016040523d82523d5f602084013e610321565b606091505b509150915081801561033557506020815110155b6103815760405162461bcd60e51b815260206004820152601960248201527f48656c7065723a206e6f6e63652072656164206661696c6564000000000000006044820152606401610279565b8080602001905181019061039591906105f0565b95945050505050565b80356001600160a01b03811681146103b4575f80fd5b919050565b5f805f805f805f60c0888a0312156103cf575f80fd5b6103d88861039e565b96506103e66020890161039e565b95506103f46040890161039e565b945060608801359350608088013567ffffffffffffffff811115610416575f80fd5b8901601f81018b13610426575f80fd5b803567ffffffffffffffff81111561043c575f80fd5b8b602082840101111561044d575f80fd5b6020919091019350915061046360a0890161039e565b905092959891949750929550565b6001600160a01b0385168152602081018490526060604082018190528101829052818360808301375f818301608090810191909152601f909201601f191601019392505050565b634e487b7160e01b5f52603260045260245ffd5b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b5f604082016040835280855180835260608501915060608160051b8601019250602087015f5b828110156105be57605f19878603018452815160018060a01b03815116865260208101516020870152604081015161010060408801526105646101008801826104cc565b9050606082015160608801526080820151608088015260a082015160a088015260c082015160c088015260e0820151915086810360e08801526105a781836104cc565b965050506020938401939190910190600101610520565b5050506001600160a01b03851660208501525090509392505050565b5f82518060208501845e5f920191825250919050565b5f60208284031215610600575f80fd5b505191905056fea2646970667358221220d1037fcc5be08c3213e2bd267a8927d2ccf6b4e6c88557b6aeec36c7135a54a764736f6c634300081a0033" + +### Setup: fund SimpleAccount's deposit on EntryPoint + +[[setup]] +kind = "deposit_to_account" +to = "{SimpleEntryPoint}" +signature = "depositTo(address account)" +args = ["{SimpleAccount}"] +value = "10 eth" + +### Setup: fund SimpleAccount directly with ETH (for paying missing funds) + +[[setup]] +kind = "fund_account" +to = "{SimpleAccount}" +value = "5 eth" + +### Spam: submit UserOperations through the helper +# Each call constructs a UserOp that calls increment() on SimpleCounter +# through the SimpleAccount, routed via the EntryPoint's two-loop handleOps. +# The helper auto-increments nonces by reading from EntryPoint. + +[[spam]] +[spam.tx] +kind = "submit_userop" +to = "{UserOpHelper}" +from_pool = "admin" +signature = "submitOp(address entryPoint, address sender, address target, uint256 value, bytes calldata innerCallData, address signerOwner)" +args = ["{SimpleEntryPoint}", "{SimpleAccount}", "{SimpleCounter}", "0", "{incrementCalldata}", "{_sender}"] +gas_limit = 500000 diff --git a/scenarios/erc4626vault.toml b/scenarios/erc4626vault.toml new file mode 100644 index 00000000..21da7e74 --- /dev/null +++ b/scenarios/erc4626vault.toml @@ -0,0 +1,103 @@ +# ERC4626 Vault deposit/withdraw spammer scenario +# +# Deploys a minimal ERC20 token (SimpleToken) and a minimal ERC4626-style vault +# (SimpleVault). Spammers repeatedly deposit and withdraw tokens to exercise +# storage-heavy DeFi patterns (balance tracking, allowances, share accounting). +# +# source: /tmp/vault.sol +# compiled with: solc --bin --optimize --optimize-runs 200 + +### template variables +[env] +initialSupply = "1000000000000000000000000000" + +### deploy SimpleToken with initialSupply +[[create]] +name = "simpleToken" +signature = "(uint256 initialSupply)" +args = ["{initialSupply}"] +bytecode = "0x60c0604052600b60809081526a29b4b6b83632aa37b5b2b760a91b60a0525f90610029908261016f565b5060408051808201909152600381526253544b60e81b6020820152600190610051908261016f565b506002805460ff1916601217905534801561006a575f80fd5b506040516109bb3803806109bb83398101604081905261008991610229565b6003819055335f818152600460209081526040808320859055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a350610240565b634e487b7160e01b5f52604160045260245ffd5b600181811c908216806100ff57607f821691505b60208210810361011d57634e487b7160e01b5f52602260045260245ffd5b50919050565b601f82111561016a57805f5260205f20601f840160051c810160208510156101485750805b601f840160051c820191505b81811015610167575f8155600101610154565b50505b505050565b81516001600160401b03811115610188576101886100d7565b61019c8161019684546100eb565b84610123565b6020601f8211600181146101ce575f83156101b75750848201515b5f19600385901b1c1916600184901b178455610167565b5f84815260208120601f198516915b828110156101fd57878501518255602094850194600190920191016101dd565b508482101561021a57868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b5f60208284031215610239575f80fd5b5051919050565b61076e8061024d5f395ff3fe608060405234801561000f575f80fd5b506004361061009b575f3560e01c806340c10f191161006357806340c10f191461012957806370a082311461013e57806395d89b411461015d578063a9059cbb14610165578063dd62ed3e14610178575f80fd5b806306fdde031461009f578063095ea7b3146100bd57806318160ddd146100e057806323b872dd146100f7578063313ce5671461010a575b5f80fd5b6100a76101a2565b6040516100b491906105c3565b60405180910390f35b6100d06100cb366004610613565b61022d565b60405190151581526020016100b4565b6100e960035481565b6040519081526020016100b4565b6100d061010536600461063b565b610299565b6002546101179060ff1681565b60405160ff90911681526020016100b4565b61013c610137366004610613565b61044f565b005b6100e961014c366004610675565b60046020525f908152604090205481565b6100a76104d5565b6100d0610173366004610613565b6104e2565b6100e9610186366004610695565b600560209081525f928352604080842090915290825290205481565b5f80546101ae906106c6565b80601f01602080910402602001604051908101604052809291908181526020018280546101da906106c6565b80156102255780601f106101fc57610100808354040283529160200191610225565b820191905f5260205f20905b81548152906001019060200180831161020857829003601f168201915b505050505081565b335f8181526005602090815260408083206001600160a01b038716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925906102879086815260200190565b60405180910390a35060015b92915050565b6001600160a01b0383165f908152600460205260408120548211156102fc5760405162461bcd60e51b8152602060048201526014602482015273696e73756666696369656e742062616c616e636560601b60448201526064015b60405180910390fd5b6001600160a01b0384165f9081526005602090815260408083203384529091529020548211156103675760405162461bcd60e51b8152602060048201526016602482015275696e73756666696369656e7420616c6c6f77616e636560501b60448201526064016102f3565b6001600160a01b0384165f90815260056020908152604080832033845290915281208054849290610399908490610712565b90915550506001600160a01b0384165f90815260046020526040812080548492906103c5908490610712565b90915550506001600160a01b0383165f90815260046020526040812080548492906103f1908490610725565b92505081905550826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161043d91815260200190565b60405180910390a35060019392505050565b8060035f8282546104609190610725565b90915550506001600160a01b0382165f908152600460205260408120805483929061048c908490610725565b90915550506040518181526001600160a01b038316905f907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b600180546101ae906106c6565b335f908152600460205260408120548211156105375760405162461bcd60e51b8152602060048201526014602482015273696e73756666696369656e742062616c616e636560601b60448201526064016102f3565b335f9081526004602052604081208054849290610555908490610712565b90915550506001600160a01b0383165f9081526004602052604081208054849290610581908490610725565b90915550506040518281526001600160a01b0384169033907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602001610287565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f83011684010191505092915050565b80356001600160a01b038116811461060e575f80fd5b919050565b5f8060408385031215610624575f80fd5b61062d836105f8565b946020939093013593505050565b5f805f6060848603121561064d575f80fd5b610656846105f8565b9250610664602085016105f8565b929592945050506040919091013590565b5f60208284031215610685575f80fd5b61068e826105f8565b9392505050565b5f80604083850312156106a6575f80fd5b6106af836105f8565b91506106bd602084016105f8565b90509250929050565b600181811c908216806106da57607f821691505b6020821081036106f857634e487b7160e01b5f52602260045260245ffd5b50919050565b634e487b7160e01b5f52601160045260245ffd5b81810381811115610293576102936106fe565b80820180821115610293576102936106fe56fea2646970667358221220737fc904479ebaf405db897f85b5c131efdffb15a46b62f70f3f7206a11b1a6764736f6c634300081a0033" + +### deploy SimpleVault with SimpleToken address +[[create]] +name = "simpleVault" +signature = "(address asset_)" +args = ["{simpleToken}"] +bytecode = "0x6080604052348015600e575f80fd5b506040516105ff3803806105ff833981016040819052602b91604e565b5f80546001600160a01b0319166001600160a01b03929092169190911790556079565b5f60208284031215605d575f80fd5b81516001600160a01b03811681146072575f80fd5b9392505050565b610579806100865f395ff3fe608060405234801561000f575f80fd5b5060043610610060575f3560e01c806301e1d114146100645780632e1a7d4d1461008057806338d52e0f146100935780633a98ef39146100bd57806370a08231146100c6578063b6b55f25146100e5575b5f80fd5b61006d60015481565b6040519081526020015b60405180910390f35b61006d61008e3660046104a9565b6100f8565b5f546100a5906001600160a01b031681565b6040516001600160a01b039091168152602001610077565b61006d60025481565b61006d6100d43660046104c0565b60036020525f908152604090205481565b61006d6100f33660046104a9565b610301565b5f80821161013d5760405162461bcd60e51b815260206004820152600d60248201526c7a65726f20776974686472617760981b60448201526064015b60405180910390fd5b335f908152600360205260409020548211156101915760405162461bcd60e51b8152602060048201526013602482015272696e73756666696369656e742073686172657360681b6044820152606401610134565b50335f908152600360205260408120805483928392916101b2908490610501565b925050819055508160025f8282546101ca9190610501565b925050819055508060015f8282546101e29190610501565b90915550505f8054604051336024820152604481018490526001600160a01b039091169060640160408051601f198184030181529181526020820180516001600160e01b031663a9059cbb60e01b1790525161023e919061051a565b5f604051808303815f865af19150503d805f8114610277576040519150601f19603f3d011682016040523d82523d5f602084013e61027c565b606091505b50509050806102bf5760405162461bcd60e51b815260206004820152600f60248201526e1d1c985b9cd9995c8819985a5b1959608a1b6044820152606401610134565b604080518481526020810184905233917ff279e6a1f5e320cca91135676d9cb6e44ca8a08c0b88342bcdb1144f6511b56891015b60405180910390a250919050565b5f8082116103405760405162461bcd60e51b815260206004820152600c60248201526b1e995c9bc819195c1bdcda5d60a21b6044820152606401610134565b505f8054604051336024820152306044820152606481018490528392916001600160a01b03169060840160408051601f198184030181529181526020820180516001600160e01b03166323b872dd60e01b1790525161039f919061051a565b5f604051808303815f865af19150503d805f81146103d8576040519150601f19603f3d011682016040523d82523d5f602084013e6103dd565b606091505b50509050806104205760405162461bcd60e51b815260206004820152600f60248201526e1d1c985b9cd9995c8819985a5b1959608a1b6044820152606401610134565b8260015f8282546104319190610530565b925050819055508160025f8282546104499190610530565b9091555050335f908152600360205260408120805484929061046c908490610530565b9091555050604080518481526020810184905233917f90890809c654f11d6e72a28fa60149770a0d11ec6c92319d6ceb2bb0a4ea1a1591016102f3565b5f602082840312156104b9575f80fd5b5035919050565b5f602082840312156104d0575f80fd5b81356001600160a01b03811681146104e6575f80fd5b9392505050565b634e487b7160e01b5f52601160045260245ffd5b81810381811115610514576105146104ed565b92915050565b5f82518060208501845e5f920191825250919050565b80820180821115610514576105146104ed56fea2646970667358221220863353e1137359eaa0b88ebf849d2ba363603da192426ee64a190a1ac748489864736f6c634300081a0033" + +## setup: admin mints tokens to self ############################################ + +[[setup]] +kind = "admin_mint_tokens" +to = "{simpleToken}" +signature = "mint(address to, uint256 amount)" +args = ["{_sender}", "1000000000000000000000000000"] + +## setup: admin approves vault to spend tokens ################################## + +[[setup]] +kind = "admin_approve_vault" +to = "{simpleToken}" +signature = "approve(address spender, uint256 amount) returns (bool)" +args = [ + "{simpleVault}", + "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", +] + +## setup: admin deposits initial tokens into vault to seed it ################### + +[[setup]] +kind = "admin_seed_vault" +to = "{simpleVault}" +signature = "deposit(uint256 assets) returns (uint256 shares)" +args = ["500000000000000000000000000"] +gas_limit = 200000 + +## setup: mint tokens to all spammer accounts ################################### + +[[setup]] +kind = "spammer_mint_tokens" +to = "{simpleToken}" +from_pool = "spammers" +for_all_accounts = true +signature = "mint(address to, uint256 amount)" +args = ["{_sender}", "100000000000000000000000"] + +## setup: all spammer accounts approve vault #################################### + +[[setup]] +kind = "spammer_approve_vault" +to = "{simpleToken}" +from_pool = "spammers" +for_all_accounts = true +signature = "approve(address spender, uint256 amount) returns (bool)" +args = [ + "{simpleVault}", + "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", +] + +### SPAM + +## spam: deposit tokens into vault (fuzz amount) ################################ + +[[spam]] +[spam.tx] +kind = "vault_deposit" +to = "{simpleVault}" +from_pool = "spammers" +signature = "deposit(uint256 assets) returns (uint256 shares)" +args = ["1000000000000000000"] +gas_limit = 200000 +fuzz = [{ param = "assets", min = "1000000000000000", max = "1000000000000000000" }] + +## spam: withdraw shares from vault (fuzz amount, may revert) #################### + +[[spam]] +[spam.tx] +kind = "vault_withdraw" +to = "{simpleVault}" +from_pool = "spammers" +signature = "withdraw(uint256 shares) returns (uint256 assets)" +args = ["100000000000000000"] +gas_limit = 200000 +fuzz = [{ param = "shares", min = "100000000000000", max = "100000000000000000" }] diff --git a/scenarios/erc721.toml b/scenarios/erc721.toml new file mode 100644 index 00000000..2a400df2 --- /dev/null +++ b/scenarios/erc721.toml @@ -0,0 +1,225 @@ +# ============================================================ +# ERC721 NFT - Minting and Transfer Stress Test +# ============================================================ +# Source: custom minimal ERC721 (/tmp/erc721.sol) +# Gas profile: ~51k mint, ~48k transferFrom +# ============================================================ +# +# This scenario deploys a minimal ERC721 contract and exercises two patterns: +# 1. Continuous minting (always succeeds, creates new state) +# 2. Self-transfers of previously minted tokens (exercises ownership checks) +# +# Setup mints tokens to all spammer accounts via for_all_accounts so each +# spammer owns tokens they can transfer. Transfer spam uses self-transfers +# ({_sender} -> {_sender}) so the sender is always the owner. + +[env] +# Number of tokens minted per spammer in setup (5 rounds x for_all_accounts) +tokens_per_spammer = "5" + +[[create]] +name = "SimpleERC721" +bytecode = "0x60c0604052600c60809081526b10dbdb9d195b99195c93919560a21b60a0525f9061002a9082610102565b5060408051808201909152600481526310d3919560e21b60208201526001906100539082610102565b506001600255348015610064575f80fd5b506101bc565b634e487b7160e01b5f52604160045260245ffd5b600181811c9082168061009257607f821691505b6020821081036100b057634e487b7160e01b5f52602260045260245ffd5b50919050565b601f8211156100fd57805f5260205f20601f840160051c810160208510156100db5750805b601f840160051c820191505b818110156100fa575f81556001016100e7565b50505b505050565b81516001600160401b0381111561011b5761011b61006a565b61012f81610129845461007e565b846100b6565b6020601f821160018114610161575f831561014a5750848201515b5f19600385901b1c1916600184901b1784556100fa565b5f84815260208120601f198516915b828110156101905787850151825560209485019460019092019101610170565b50848210156101ad57868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b610a94806101c95f395ff3fe608060405234801561000f575f80fd5b506004361061009b575f3560e01c80636a627842116100635780636a6278421461012357806370a082311461014457806395d89b4114610157578063a22cb4651461015f578063e985e9c514610172575f80fd5b806306fdde031461009f578063081812fc146100bd578063095ea7b3146100e857806323b872dd146100fd5780636352211e14610110575b5f80fd5b6100a76101bd565b6040516100b49190610881565b60405180910390f35b6100d06100cb3660046108b6565b610248565b6040516001600160a01b0390911681526020016100b4565b6100fb6100f63660046108e8565b6102c7565b005b6100fb61010b366004610910565b6103ac565b6100d061011e3660046108b6565b6105eb565b61013661013136600461094a565b610651565b6040519081526020016100b4565b61013661015236600461094a565b610748565b6100a76107b1565b6100fb61016d36600461096a565b6107be565b6101ad6101803660046109a3565b6001600160a01b039182165f90815260066020908152604080832093909416825291909152205460ff1690565b60405190151581526020016100b4565b5f80546101c9906109d4565b80601f01602080910402602001604051908101604052809291908181526020018280546101f5906109d4565b80156102405780601f1061021757610100808354040283529160200191610240565b820191905f5260205f20905b81548152906001019060200180831161022357829003601f168201915b505050505081565b5f818152600360205260408120546001600160a01b03166102ac5760405162461bcd60e51b815260206004820152601960248201527822a9219b99189d103737b732bc34b9ba32b73a103a37b5b2b760391b60448201526064015b60405180910390fd5b505f908152600560205260409020546001600160a01b031690565b5f6102d1826105eb565b9050336001600160a01b038216148061030c57506001600160a01b0381165f90815260066020908152604080832033845290915290205460ff165b6103515760405162461bcd60e51b8152602060048201526016602482015275115490cdcc8c4e881b9bdd08185d5d1a1bdc9a5e995960521b60448201526064016102a3565b5f8281526005602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b5f6103b6826105eb565b9050836001600160a01b0316816001600160a01b0316146104275760405162461bcd60e51b815260206004820152602560248201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060448201526437bbb732b960d91b60648201526084016102a3565b6001600160a01b03831661047d5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a207472616e7366657220746f207a65726f206164647265737360448201526064016102a3565b336001600160a01b03821614806104a957505f828152600560205260409020546001600160a01b031633145b806104d657506001600160a01b0381165f90815260066020908152604080832033845290915290205460ff165b61051b5760405162461bcd60e51b8152602060048201526016602482015275115490cdcc8c4e881b9bdd08185d5d1a1bdc9a5e995960521b60448201526064016102a3565b5f82815260056020908152604080832080546001600160a01b03191690556001600160a01b03871683526004909152812080546001929061055d908490610a20565b90915550506001600160a01b0383165f90815260046020526040812080546001929061058a908490610a33565b90915550505f8281526003602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918816917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a450505050565b5f818152600360205260408120546001600160a01b03168061064b5760405162461bcd60e51b815260206004820152601960248201527822a9219b99189d103737b732bc34b9ba32b73a103a37b5b2b760391b60448201526064016102a3565b92915050565b5f6001600160a01b0382166106a85760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a206d696e7420746f207a65726f20616464726573730000000060448201526064016102a3565b600280545f91826106b883610a46565b909155506001600160a01b0384165f90815260046020526040812080549293506001929091906106e9908490610a33565b90915550505f8181526003602052604080822080546001600160a01b0319166001600160a01b03871690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a492915050565b5f6001600160a01b0382166107965760405162461bcd60e51b81526020600482015260146024820152734552433732313a207a65726f206164647265737360601b60448201526064016102a3565b506001600160a01b03165f9081526004602052604090205490565b600180546101c9906109d4565b336001600160a01b038316036108165760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c65720000000000000060448201526064016102a3565b335f8181526006602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f83011684010191505092915050565b5f602082840312156108c6575f80fd5b5035919050565b80356001600160a01b03811681146108e3575f80fd5b919050565b5f80604083850312156108f9575f80fd5b610902836108cd565b946020939093013593505050565b5f805f60608486031215610922575f80fd5b61092b846108cd565b9250610939602085016108cd565b929592945050506040919091013590565b5f6020828403121561095a575f80fd5b610963826108cd565b9392505050565b5f806040838503121561097b575f80fd5b610984836108cd565b915060208301358015158114610998575f80fd5b809150509250929050565b5f80604083850312156109b4575f80fd5b6109bd836108cd565b91506109cb602084016108cd565b90509250929050565b600181811c908216806109e857607f821691505b602082108103610a0657634e487b7160e01b5f52602260045260245ffd5b50919050565b634e487b7160e01b5f52601160045260245ffd5b8181038181111561064b5761064b610a0c565b8082018082111561064b5761064b610a0c565b5f60018201610a5757610a57610a0c565b506001019056fea2646970667358221220be6f9adf2f2741393e6e03d0ac12e184e5667c342af1376d1b7fd352e6d3ade264736f6c634300081a0033" + +# Setup: admin mints 20 tokens to seed initial supply (token IDs 1-20) +[[setup]] +kind = "admin_mint_01" +to = "{SimpleERC721}" +from_pool = "admin" +signature = "mint(address to)" +args = ["{_sender}"] + +[[setup]] +kind = "admin_mint_02" +to = "{SimpleERC721}" +from_pool = "admin" +signature = "mint(address to)" +args = ["{_sender}"] + +[[setup]] +kind = "admin_mint_03" +to = "{SimpleERC721}" +from_pool = "admin" +signature = "mint(address to)" +args = ["{_sender}"] + +[[setup]] +kind = "admin_mint_04" +to = "{SimpleERC721}" +from_pool = "admin" +signature = "mint(address to)" +args = ["{_sender}"] + +[[setup]] +kind = "admin_mint_05" +to = "{SimpleERC721}" +from_pool = "admin" +signature = "mint(address to)" +args = ["{_sender}"] + +[[setup]] +kind = "admin_mint_06" +to = "{SimpleERC721}" +from_pool = "admin" +signature = "mint(address to)" +args = ["{_sender}"] + +[[setup]] +kind = "admin_mint_07" +to = "{SimpleERC721}" +from_pool = "admin" +signature = "mint(address to)" +args = ["{_sender}"] + +[[setup]] +kind = "admin_mint_08" +to = "{SimpleERC721}" +from_pool = "admin" +signature = "mint(address to)" +args = ["{_sender}"] + +[[setup]] +kind = "admin_mint_09" +to = "{SimpleERC721}" +from_pool = "admin" +signature = "mint(address to)" +args = ["{_sender}"] + +[[setup]] +kind = "admin_mint_10" +to = "{SimpleERC721}" +from_pool = "admin" +signature = "mint(address to)" +args = ["{_sender}"] + +[[setup]] +kind = "admin_mint_11" +to = "{SimpleERC721}" +from_pool = "admin" +signature = "mint(address to)" +args = ["{_sender}"] + +[[setup]] +kind = "admin_mint_12" +to = "{SimpleERC721}" +from_pool = "admin" +signature = "mint(address to)" +args = ["{_sender}"] + +[[setup]] +kind = "admin_mint_13" +to = "{SimpleERC721}" +from_pool = "admin" +signature = "mint(address to)" +args = ["{_sender}"] + +[[setup]] +kind = "admin_mint_14" +to = "{SimpleERC721}" +from_pool = "admin" +signature = "mint(address to)" +args = ["{_sender}"] + +[[setup]] +kind = "admin_mint_15" +to = "{SimpleERC721}" +from_pool = "admin" +signature = "mint(address to)" +args = ["{_sender}"] + +[[setup]] +kind = "admin_mint_16" +to = "{SimpleERC721}" +from_pool = "admin" +signature = "mint(address to)" +args = ["{_sender}"] + +[[setup]] +kind = "admin_mint_17" +to = "{SimpleERC721}" +from_pool = "admin" +signature = "mint(address to)" +args = ["{_sender}"] + +[[setup]] +kind = "admin_mint_18" +to = "{SimpleERC721}" +from_pool = "admin" +signature = "mint(address to)" +args = ["{_sender}"] + +[[setup]] +kind = "admin_mint_19" +to = "{SimpleERC721}" +from_pool = "admin" +signature = "mint(address to)" +args = ["{_sender}"] + +[[setup]] +kind = "admin_mint_20" +to = "{SimpleERC721}" +from_pool = "admin" +signature = "mint(address to)" +args = ["{_sender}"] + +# Setup: mint 5 tokens to every spammer account so they own tokens for transfers +# Token IDs start at 21 and continue sequentially across all spammer accounts +[[setup]] +kind = "spammer_mint_1" +to = "{SimpleERC721}" +from_pool = "spammer" +for_all_accounts = true +signature = "mint(address to)" +args = ["{_sender}"] + +[[setup]] +kind = "spammer_mint_2" +to = "{SimpleERC721}" +from_pool = "spammer" +for_all_accounts = true +signature = "mint(address to)" +args = ["{_sender}"] + +[[setup]] +kind = "spammer_mint_3" +to = "{SimpleERC721}" +from_pool = "spammer" +for_all_accounts = true +signature = "mint(address to)" +args = ["{_sender}"] + +[[setup]] +kind = "spammer_mint_4" +to = "{SimpleERC721}" +from_pool = "spammer" +for_all_accounts = true +signature = "mint(address to)" +args = ["{_sender}"] + +[[setup]] +kind = "spammer_mint_5" +to = "{SimpleERC721}" +from_pool = "spammer" +for_all_accounts = true +signature = "mint(address to)" +args = ["{_sender}"] + +# Spam 1: Continuous minting of new tokens (always succeeds) +# Each tx mints a new NFT to the sender, creating fresh state writes +[[spam]] +[spam.tx] +kind = "nft_mint" +to = "{SimpleERC721}" +signature = "mint(address to)" +args = ["{_sender}"] + +# Spam 2: Self-transfers of tokens (sender transfers to self) +# Uses fuzzed tokenId; some may revert if sender doesn't own that token, +# which is realistic for benchmarking revert-handling throughput +[[spam]] +[spam.tx] +kind = "nft_transfer" +to = "{SimpleERC721}" +signature = "transferFrom(address from, address to, uint256 tokenId)" +args = ["{_sender}", "{_sender}", "1"] +fuzz = [{ param = "tokenId", min = "1", max = "1000" }] diff --git a/scenarios/flashLoan.toml b/scenarios/flashLoan.toml new file mode 100644 index 00000000..bf11fbbc --- /dev/null +++ b/scenarios/flashLoan.toml @@ -0,0 +1,146 @@ +# Flash Loan Arbitrage scenario +# +# Deploys a flash loan provider (ERC-3156), two fixed-rate swap pools with +# different exchange rates, and an arbitrage bot that borrows via flash loan, +# swaps through both pools to capture the rate difference, and repays atomically. +# +# This creates a deep call stack (4-5 levels): +# Spammer -> FlashBorrower.executeArbitrage -> FlashLender.flashLoan +# -> FlashBorrower.onFlashLoan -> PoolA.swap -> PoolB.swap -> repay +# +# Contracts: +# - FlashToken: Minimal ERC20 with public mint (deployed twice as TokenA & TokenB) +# - FlashLender: ERC-3156 flash loan provider (0.1% fee) +# - SimplePool: Fixed exchange rate swap pool (deployed twice with different rates) +# - FlashBorrower: Arbitrage bot that chains borrow -> multi-DEX arb -> repay +# +# source: /tmp/flashloan.sol +# compiled with: solc --bin --optimize --optimize-runs 200 /tmp/flashloan.sol + +[env] +initialSupply = "1000000000000000000000000000" +lenderFunds = "500000000000000000000000000" +poolFunds = "200000000000000000000000000" +borrowerFunds = "1000000000000000000000" + +### Deploy contracts ########################################################### + +[[create]] +name = "TokenA" +signature = "(string memory name_, string memory symbol_, uint256 initialSupply)" +args = ["TokenA", "TKA", "{initialSupply}"] +# FlashToken bytecode +bytecode = "0x608060405234801561000f575f80fd5b5060405161095738038061095783398101604081905261002e91610134565b5f6100398482610225565b5060016100468382610225565b506002819055335f818152600360209081526040808320859055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050506102df565b634e487b7160e01b5f52604160045260245ffd5b5f82601f8301126100ba575f80fd5b81516001600160401b038111156100d3576100d3610097565b604051601f8201601f19908116603f011681016001600160401b038111828210171561010157610101610097565b604052818152838201602001851015610118575f80fd5b8160208501602083015e5f918101602001919091529392505050565b5f805f60608486031215610146575f80fd5b83516001600160401b0381111561015b575f80fd5b610167868287016100ab565b602086015190945090506001600160401b03811115610184575f80fd5b610190868287016100ab565b925050604084015190509250925092565b600181811c908216806101b557607f821691505b6020821081036101d357634e487b7160e01b5f52602260045260245ffd5b50919050565b601f82111561022057805f5260205f20601f840160051c810160208510156101fe5750805b601f840160051c820191505b8181101561021d575f815560010161020a565b50505b505050565b81516001600160401b0381111561023e5761023e610097565b6102528161024c84546101a1565b846101d9565b6020601f821160018114610284575f831561026d5750848201515b5f19600385901b1c1916600184901b17845561021d565b5f84815260208120601f198516915b828110156102b35787850151825560209485019460019092019101610293565b50848210156102d057868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b61066b806102ec5f395ff3fe608060405234801561000f575f80fd5b506004361061009b575f3560e01c806340c10f191161006357806340c10f191461012457806370a082311461013957806395d89b4114610158578063a9059cbb14610160578063dd62ed3e14610173575f80fd5b806306fdde031461009f578063095ea7b3146100bd57806318160ddd146100e057806323b872dd146100f7578063313ce5671461010a575b5f80fd5b6100a761019d565b6040516100b491906104c0565b60405180910390f35b6100d06100cb366004610510565b610228565b60405190151581526020016100b4565b6100e960025481565b6040519081526020016100b4565b6100d0610105366004610538565b610294565b610112601281565b60405160ff90911681526020016100b4565b610137610132366004610510565b61039f565b005b6100e9610147366004610572565b60036020525f908152604090205481565b6100a7610425565b6100d061016e366004610510565b610432565b6100e9610181366004610592565b600460209081525f928352604080842090915290825290205481565b5f80546101a9906105c3565b80601f01602080910402602001604051908101604052809291908181526020018280546101d5906105c3565b80156102205780601f106101f757610100808354040283529160200191610220565b820191905f5260205f20905b81548152906001019060200180831161020357829003601f168201915b505050505081565b335f8181526004602090815260408083206001600160a01b038716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925906102829086815260200190565b60405180910390a35060015b92915050565b6001600160a01b0383165f9081526004602090815260408083203384529091528120545f1981146102ed576102c9838261060f565b6001600160a01b0386165f9081526004602090815260408083203384529091529020555b6001600160a01b0385165f908152600360205260408120805485929061031490849061060f565b90915550506001600160a01b0384165f9081526003602052604081208054859290610340908490610622565b92505081905550836001600160a01b0316856001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8560405161038c91815260200190565b60405180910390a3506001949350505050565b8060025f8282546103b09190610622565b90915550506001600160a01b0382165f90815260036020526040812080548392906103dc908490610622565b90915550506040518181526001600160a01b038316905f907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b600180546101a9906105c3565b335f9081526003602052604081208054839190839061045290849061060f565b90915550506001600160a01b0383165f908152600360205260408120805484929061047e908490610622565b90915550506040518281526001600160a01b0384169033907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602001610282565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f83011684010191505092915050565b80356001600160a01b038116811461050b575f80fd5b919050565b5f8060408385031215610521575f80fd5b61052a836104f5565b946020939093013593505050565b5f805f6060848603121561054a575f80fd5b610553846104f5565b9250610561602085016104f5565b929592945050506040919091013590565b5f60208284031215610582575f80fd5b61058b826104f5565b9392505050565b5f80604083850312156105a3575f80fd5b6105ac836104f5565b91506105ba602084016104f5565b90509250929050565b600181811c908216806105d757607f821691505b6020821081036105f557634e487b7160e01b5f52602260045260245ffd5b50919050565b634e487b7160e01b5f52601160045260245ffd5b8181038181111561028e5761028e6105fb565b8082018082111561028e5761028e6105fb56fea2646970667358221220a5c1827faa15b81b6f39b5c76029840eb76518cd0988498092c3958175a7f34464736f6c634300081a0033" + +[[create]] +name = "TokenB" +signature = "(string memory name_, string memory symbol_, uint256 initialSupply)" +args = ["TokenB", "TKB", "{initialSupply}"] +# FlashToken bytecode (same contract, different constructor args) +bytecode = "0x608060405234801561000f575f80fd5b5060405161095738038061095783398101604081905261002e91610134565b5f6100398482610225565b5060016100468382610225565b506002819055335f818152600360209081526040808320859055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050506102df565b634e487b7160e01b5f52604160045260245ffd5b5f82601f8301126100ba575f80fd5b81516001600160401b038111156100d3576100d3610097565b604051601f8201601f19908116603f011681016001600160401b038111828210171561010157610101610097565b604052818152838201602001851015610118575f80fd5b8160208501602083015e5f918101602001919091529392505050565b5f805f60608486031215610146575f80fd5b83516001600160401b0381111561015b575f80fd5b610167868287016100ab565b602086015190945090506001600160401b03811115610184575f80fd5b610190868287016100ab565b925050604084015190509250925092565b600181811c908216806101b557607f821691505b6020821081036101d357634e487b7160e01b5f52602260045260245ffd5b50919050565b601f82111561022057805f5260205f20601f840160051c810160208510156101fe5750805b601f840160051c820191505b8181101561021d575f815560010161020a565b50505b505050565b81516001600160401b0381111561023e5761023e610097565b6102528161024c84546101a1565b846101d9565b6020601f821160018114610284575f831561026d5750848201515b5f19600385901b1c1916600184901b17845561021d565b5f84815260208120601f198516915b828110156102b35787850151825560209485019460019092019101610293565b50848210156102d057868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b61066b806102ec5f395ff3fe608060405234801561000f575f80fd5b506004361061009b575f3560e01c806340c10f191161006357806340c10f191461012457806370a082311461013957806395d89b4114610158578063a9059cbb14610160578063dd62ed3e14610173575f80fd5b806306fdde031461009f578063095ea7b3146100bd57806318160ddd146100e057806323b872dd146100f7578063313ce5671461010a575b5f80fd5b6100a761019d565b6040516100b491906104c0565b60405180910390f35b6100d06100cb366004610510565b610228565b60405190151581526020016100b4565b6100e960025481565b6040519081526020016100b4565b6100d0610105366004610538565b610294565b610112601281565b60405160ff90911681526020016100b4565b610137610132366004610510565b61039f565b005b6100e9610147366004610572565b60036020525f908152604090205481565b6100a7610425565b6100d061016e366004610510565b610432565b6100e9610181366004610592565b600460209081525f928352604080842090915290825290205481565b5f80546101a9906105c3565b80601f01602080910402602001604051908101604052809291908181526020018280546101d5906105c3565b80156102205780601f106101f757610100808354040283529160200191610220565b820191905f5260205f20905b81548152906001019060200180831161020357829003601f168201915b505050505081565b335f8181526004602090815260408083206001600160a01b038716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925906102829086815260200190565b60405180910390a35060015b92915050565b6001600160a01b0383165f9081526004602090815260408083203384529091528120545f1981146102ed576102c9838261060f565b6001600160a01b0386165f9081526004602090815260408083203384529091529020555b6001600160a01b0385165f908152600360205260408120805485929061031490849061060f565b90915550506001600160a01b0384165f9081526003602052604081208054859290610340908490610622565b92505081905550836001600160a01b0316856001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8560405161038c91815260200190565b60405180910390a3506001949350505050565b8060025f8282546103b09190610622565b90915550506001600160a01b0382165f90815260036020526040812080548392906103dc908490610622565b90915550506040518181526001600160a01b038316905f907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b600180546101a9906105c3565b335f9081526003602052604081208054839190839061045290849061060f565b90915550506001600160a01b0383165f908152600360205260408120805484929061047e908490610622565b90915550506040518281526001600160a01b0384169033907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602001610282565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f83011684010191505092915050565b80356001600160a01b038116811461050b575f80fd5b919050565b5f8060408385031215610521575f80fd5b61052a836104f5565b946020939093013593505050565b5f805f6060848603121561054a575f80fd5b610553846104f5565b9250610561602085016104f5565b929592945050506040919091013590565b5f60208284031215610582575f80fd5b61058b826104f5565b9392505050565b5f80604083850312156105a3575f80fd5b6105ac836104f5565b91506105ba602084016104f5565b90509250929050565b600181811c908216806105d757607f821691505b6020821081036105f557634e487b7160e01b5f52602260045260245ffd5b50919050565b634e487b7160e01b5f52601160045260245ffd5b8181038181111561028e5761028e6105fb565b8082018082111561028e5761028e6105fb56fea2646970667358221220a5c1827faa15b81b6f39b5c76029840eb76518cd0988498092c3958175a7f34464736f6c634300081a0033" + +[[create]] +name = "FlashLender" +signature = "(address token_)" +args = ["{TokenA}"] +# FlashLender bytecode +bytecode = "0x6080604052348015600e575f80fd5b50604051610851380380610851833981016040819052602b91604e565b5f80546001600160a01b0319166001600160a01b03929092169190911790556079565b5f60208284031215605d575f80fd5b81516001600160a01b03811681146072575f80fd5b9392505050565b6107cb806100865f395ff3fe608060405234801561000f575f80fd5b5060043610610060575f3560e01c80635cffe9de14610064578063613255ab1461008c5780638237e538146100ad578063d9d98ce4146100d4578063dd49756e146100e7578063fc0c546a146100fc575b5f80fd5b6100776100723660046105dc565b610126565b60405190151581526020015b60405180910390f35b61009f61009a366004610671565b610456565b604051908152602001610083565b61009f7f439148f0bbc682ca079e46d6e2c2f0c1e3b820f1a291b069d8882abf8cf18dd981565b61009f6100e236600461068a565b6104e2565b6100fa6100f53660046106b2565b610546565b005b5f5461010e906001600160a01b031681565b6040516001600160a01b039091168152602001610083565b5f80546001600160a01b0386811691161461017c5760405162461bcd60e51b81526020600482015260116024820152703ab739bab83837b93a32b2103a37b5b2b760791b60448201526064015b60405180910390fd5b5f61018786866104e2565b5f80546040516370a0823160e01b815230600482015292935090916001600160a01b03909116906370a0823190602401602060405180830381865afa1580156101d2573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906101f691906106c9565b9050858110156102415760405162461bcd60e51b8152602060048201526016602482015275696e73756666696369656e74206c697175696469747960501b6044820152606401610173565b5f5460405163a9059cbb60e01b81526001600160a01b038a81166004830152602482018990529091169063a9059cbb906044016020604051808303815f875af1158015610290573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906102b491906106e0565b506040516323e30c8b60e01b81525f906001600160a01b038a16906323e30c8b906102ed9033908c908c9089908d908d906004016106ff565b6020604051808303815f875af1158015610309573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061032d91906106c9565b90507f439148f0bbc682ca079e46d6e2c2f0c1e3b820f1a291b069d8882abf8cf18dd981146103945760405162461bcd60e51b81526020600482015260136024820152723130b21031b0b6363130b1b5903932ba3ab93760691b6044820152606401610173565b5f80546040516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa1580156103da573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906103fe91906106c9565b905061040a8484610757565b8110156104465760405162461bcd60e51b815260206004820152600a6024820152691b9bdd081c995c185a5960b21b6044820152606401610173565b5060019998505050505050505050565b5f80546001600160a01b03908116908316036104db575f546040516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa1580156104b1573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906104d591906106c9565b92915050565b505f919050565b5f80546001600160a01b038481169116146105335760405162461bcd60e51b81526020600482015260116024820152703ab739bab83837b93a32b2103a37b5b2b760791b6044820152606401610173565b61053f6103e883610776565b9392505050565b5f546040516323b872dd60e01b8152336004820152306024820152604481018390526001600160a01b03909116906323b872dd906064016020604051808303815f875af1158015610599573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906105bd91906106e0565b5050565b80356001600160a01b03811681146105d7575f80fd5b919050565b5f805f805f608086880312156105f0575f80fd5b6105f9866105c1565b9450610607602087016105c1565b935060408601359250606086013567ffffffffffffffff811115610629575f80fd5b8601601f81018813610639575f80fd5b803567ffffffffffffffff81111561064f575f80fd5b886020828401011115610660575f80fd5b959894975092955050506020019190565b5f60208284031215610681575f80fd5b61053f826105c1565b5f806040838503121561069b575f80fd5b6106a4836105c1565b946020939093013593505050565b5f602082840312156106c2575f80fd5b5035919050565b5f602082840312156106d9575f80fd5b5051919050565b5f602082840312156106f0575f80fd5b8151801515811461053f575f80fd5b6001600160a01b03878116825286166020820152604081018590526060810184905260a0608082018190528101829052818360c08301375f81830160c090810191909152601f909201601f1916010195945050505050565b808201808211156104d557634e487b7160e01b5f52601160045260245ffd5b5f8261079057634e487b7160e01b5f52601260045260245ffd5b50049056fea264697066735822122079694df1a110017a0f8249369c96418802ee4a927b1648fafcfebb7bce7bf36264736f6c634300081a0033" + +# PoolA: 1 TokenA = 1.05 TokenB (rate 105/100) +[[create]] +name = "PoolA" +signature = "(address tokenA_, address tokenB_, uint256 rateNumerator_, uint256 rateDenominator_)" +args = ["{TokenA}", "{TokenB}", "105", "100"] +# SimplePool bytecode +bytecode = "0x6080604052348015600e575f80fd5b5060405161042d38038061042d833981016040819052602b916081565b5f80546001600160a01b039586166001600160a01b031991821617909155600180549490951693169290921790925560029190915560035560bc565b80516001600160a01b0381168114607c575f80fd5b919050565b5f805f80608085870312156093575f80fd5b609a856067565b935060a6602086016067565b6040860151606090960151949790965092505050565b610364806100c95f395ff3fe608060405234801561000f575f80fd5b5060043610610055575f3560e01c80630b36b8db146100595780630fc63d10146100755780635f64b55b1461009f578063865192f7146100b2578063d004f0f7146100bb575b5f80fd5b61006260025481565b6040519081526020015b60405180910390f35b5f54610087906001600160a01b031681565b6040516001600160a01b03909116815260200161006c565b600154610087906001600160a01b031681565b61006260035481565b6100626100c9366004610291565b5f80546001600160a01b03848116911614806100f257506001546001600160a01b038481169116145b6101325760405162461bcd60e51b815260206004820152600d60248201526c34b73b30b634b2103a37b5b2b760991b604482015260640160405180910390fd5b5f80546001600160a01b039081169085160361017957506001546003546002546001600160a01b039092169161016890856102c6565b61017291906102e9565b91506101a5565b505f546003546002546001600160a01b039092169161019890856102c6565b6101a291906102e9565b91505b6040516323b872dd60e01b8152336004820152306024820152604481018490526001600160a01b038516906323b872dd906064016020604051808303815f875af11580156101f5573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906102199190610308565b5060405163a9059cbb60e01b8152336004820152602481018390526001600160a01b0382169063a9059cbb906044016020604051808303815f875af1158015610264573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906102889190610308565b50505b92915050565b5f80604083850312156102a2575f80fd5b82356001600160a01b03811681146102b8575f80fd5b946020939093013593505050565b808202811582820484141761028b57634e487b7160e01b5f52601160045260245ffd5b5f8261030357634e487b7160e01b5f52601260045260245ffd5b500490565b5f60208284031215610318575f80fd5b81518015158114610327575f80fd5b939250505056fea26469706673582212202d333b1b053b11f4f88e6624810e0bc49abdda5fa3cd40cbbacdecb87532381d64736f6c634300081a0033" + +# PoolB: 1 TokenB = 1.05 TokenA (rate 105/100, reverse direction) +# This means: swap TokenB->TokenA at 105/100, combined with PoolA's TokenA->TokenB at 105/100 +# gives profit: 100 TokenA -> 105 TokenB -> 110.25 TokenA (net ~10% profit minus 0.1% fee) +[[create]] +name = "PoolB" +signature = "(address tokenA_, address tokenB_, uint256 rateNumerator_, uint256 rateDenominator_)" +args = ["{TokenB}", "{TokenA}", "105", "100"] +# SimplePool bytecode (same contract, different constructor args) +bytecode = "0x6080604052348015600e575f80fd5b5060405161042d38038061042d833981016040819052602b916081565b5f80546001600160a01b039586166001600160a01b031991821617909155600180549490951693169290921790925560029190915560035560bc565b80516001600160a01b0381168114607c575f80fd5b919050565b5f805f80608085870312156093575f80fd5b609a856067565b935060a6602086016067565b6040860151606090960151949790965092505050565b610364806100c95f395ff3fe608060405234801561000f575f80fd5b5060043610610055575f3560e01c80630b36b8db146100595780630fc63d10146100755780635f64b55b1461009f578063865192f7146100b2578063d004f0f7146100bb575b5f80fd5b61006260025481565b6040519081526020015b60405180910390f35b5f54610087906001600160a01b031681565b6040516001600160a01b03909116815260200161006c565b600154610087906001600160a01b031681565b61006260035481565b6100626100c9366004610291565b5f80546001600160a01b03848116911614806100f257506001546001600160a01b038481169116145b6101325760405162461bcd60e51b815260206004820152600d60248201526c34b73b30b634b2103a37b5b2b760991b604482015260640160405180910390fd5b5f80546001600160a01b039081169085160361017957506001546003546002546001600160a01b039092169161016890856102c6565b61017291906102e9565b91506101a5565b505f546003546002546001600160a01b039092169161019890856102c6565b6101a291906102e9565b91505b6040516323b872dd60e01b8152336004820152306024820152604481018490526001600160a01b038516906323b872dd906064016020604051808303815f875af11580156101f5573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906102199190610308565b5060405163a9059cbb60e01b8152336004820152602481018390526001600160a01b0382169063a9059cbb906044016020604051808303815f875af1158015610264573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906102889190610308565b50505b92915050565b5f80604083850312156102a2575f80fd5b82356001600160a01b03811681146102b8575f80fd5b946020939093013593505050565b808202811582820484141761028b57634e487b7160e01b5f52601160045260245ffd5b5f8261030357634e487b7160e01b5f52601260045260245ffd5b500490565b5f60208284031215610318575f80fd5b81518015158114610327575f80fd5b939250505056fea26469706673582212202d333b1b053b11f4f88e6624810e0bc49abdda5fa3cd40cbbacdecb87532381d64736f6c634300081a0033" + +[[create]] +name = "FlashBorrower" +signature = "()" +args = [] +# FlashBorrower bytecode +bytecode = "0x6080604052348015600e575f80fd5b506107078061001c5f395ff3fe608060405234801561000f575f80fd5b506004361061003f575f3560e01c806323e30c8b1461004357806372bf1a44146100685780638237e5381461007d575b5f80fd5b6100566100513660046104b3565b6100a4565b60405190815260200160405180910390f35b61007b610076366004610558565b6103f1565b005b6100567f439148f0bbc682ca079e46d6e2c2f0c1e3b820f1a291b069d8882abf8cf18dd981565b5f8080806100b4858701876105cd565b60405163095ea7b360e01b81526001600160a01b038085166004830152602482018d90529396509194509250908a169063095ea7b3906044016020604051808303815f875af1158015610109573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061012d9190610615565b5060405163d004f0f760e01b81526001600160a01b038a81166004830152602482018a90525f919085169063d004f0f7906044016020604051808303815f875af115801561017d573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906101a1919061063b565b60405163095ea7b360e01b81526001600160a01b038581166004830152602482018390529192509083169063095ea7b3906044016020604051808303815f875af11580156101f1573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906102159190610615565b5060405163d004f0f760e01b81526001600160a01b038381166004830152602482018390525f919085169063d004f0f7906044016020604051808303815f875af1158015610265573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610289919061063b565b90505f6102968a8c610652565b9050808210156102e15760405162461bcd60e51b8152602060048201526012602482015271617262206e6f742070726f66697461626c6560701b604482015260640160405180910390fd5b60405163095ea7b360e01b8152336004820152602481018290526001600160a01b038d169063095ea7b3906044016020604051808303815f875af115801561032b573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061034f9190610615565b5060405163a9059cbb60e01b8152336004820152602481018290526001600160a01b038d169063a9059cbb906044016020604051808303815f875af115801561039a573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906103be9190610615565b507f439148f0bbc682ca079e46d6e2c2f0c1e3b820f1a291b069d8882abf8cf18dd99d9c50505050505050505050505050565b604080516001600160a01b03858116602083015284811682840152838116606080840191909152835180840390910181526080830193849052632e7ff4ef60e11b909352881690635cffe9de906104529030908a908a908790608401610677565b6020604051808303815f875af115801561046e573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906104929190610615565b5050505050505050565b6001600160a01b03811681146104b0575f80fd5b50565b5f805f805f8060a087890312156104c8575f80fd5b86356104d38161049c565b955060208701356104e38161049c565b94506040870135935060608701359250608087013567ffffffffffffffff81111561050c575f80fd5b8701601f8101891361051c575f80fd5b803567ffffffffffffffff811115610532575f80fd5b896020828401011115610543575f80fd5b60208201935080925050509295509295509295565b5f805f805f8060c0878903121561056d575f80fd5b86356105788161049c565b955060208701356105888161049c565b945060408701359350606087013561059f8161049c565b925060808701356105af8161049c565b915060a08701356105bf8161049c565b809150509295509295509295565b5f805f606084860312156105df575f80fd5b83356105ea8161049c565b925060208401356105fa8161049c565b9150604084013561060a8161049c565b809150509250925092565b5f60208284031215610625575f80fd5b81518015158114610634575f80fd5b9392505050565b5f6020828403121561064b575f80fd5b5051919050565b8082018082111561067157634e487b7160e01b5f52601160045260245ffd5b92915050565b60018060a01b038516815260018060a01b0384166020820152826040820152608060608201525f8251806080840152806020850160a085015e5f60a0828501015260a0601f19601f8301168401019150509594505050505056fea2646970667358221220987cea3d57cf1d9e2e5c2b7cada7361c611b88880bad6aae03073e77126f06ce64736f6c634300081a0033" + + +### Setup contracts ############################################################# + +## Admin approves FlashLender to pull TokenA (for depositTokens) +[[setup]] +kind = "admin_approve_lender" +to = "{TokenA}" +signature = "approve(address spender, uint256 amount) returns (bool)" +args = [ + "{FlashLender}", + "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", +] + +## Admin deposits TokenA into FlashLender pool +[[setup]] +kind = "admin_deposit_to_lender" +to = "{FlashLender}" +signature = "depositTokens(uint256 amount)" +args = ["{lenderFunds}"] + +## Admin funds PoolA with TokenA +[[setup]] +kind = "admin_fund_poolA_tokenA" +to = "{TokenA}" +signature = "transfer(address to, uint256 amount) returns (bool)" +args = ["{PoolA}", "{poolFunds}"] + +## Admin funds PoolA with TokenB +[[setup]] +kind = "admin_fund_poolA_tokenB" +to = "{TokenB}" +signature = "transfer(address to, uint256 amount) returns (bool)" +args = ["{PoolA}", "{poolFunds}"] + +## Admin funds PoolB with TokenA +[[setup]] +kind = "admin_fund_poolB_tokenA" +to = "{TokenA}" +signature = "transfer(address to, uint256 amount) returns (bool)" +args = ["{PoolB}", "{poolFunds}"] + +## Admin funds PoolB with TokenB +[[setup]] +kind = "admin_fund_poolB_tokenB" +to = "{TokenB}" +signature = "transfer(address to, uint256 amount) returns (bool)" +args = ["{PoolB}", "{poolFunds}"] + +## Admin funds FlashBorrower with small amount of TokenA (to cover profit leftovers) +[[setup]] +kind = "admin_fund_borrower_tokenA" +to = "{TokenA}" +signature = "transfer(address to, uint256 amount) returns (bool)" +args = ["{FlashBorrower}", "{borrowerFunds}"] + + +### Spam patterns ############################################################## + +# Execute flash loan arbitrage: +# FlashBorrower.executeArbitrage -> FlashLender.flashLoan -> onFlashLoan callback +# -> PoolA.swap (TokenA->TokenB) -> PoolB.swap (TokenB->TokenA) -> repay lender +# Fuzz the flash loan amount from 1e18 to 1e20 +[[spam]] +[spam.tx] +kind = "flash_loan_arbitrage" +to = "{FlashBorrower}" +from_pool = "spammer" +signature = "executeArbitrage(address lender, address token, uint256 amount, address poolA, address poolB, address tokenB)" +args = ["{FlashLender}", "{TokenA}", "1000000000000000000", "{PoolA}", "{PoolB}", "{TokenB}"] +gas_limit = 500000 +fuzz = [ + { param = "amount", min = "1000000000000000000", max = "100000000000000000000" }, +] diff --git a/scenarios/governance.toml b/scenarios/governance.toml new file mode 100644 index 00000000..b124b309 --- /dev/null +++ b/scenarios/governance.toml @@ -0,0 +1,95 @@ +# SimpleGovernance scenario +# Simulates on-chain governance voting with realistic gas patterns: +# storage writes for vote tracking, event emission, and require checks. +# source: /tmp/governance.sol (Solidity 0.8.26, optimized with 200 runs) + +## Deploy the governance contract +[[create]] +name = "SimpleGovernance" +bytecode = "0x6080604052348015600e575f80fd5b5061052a8061001c5f395ff3fe608060405234801561000f575f80fd5b5060043610610060575f3560e01c8063013cf08b1461006457806343859632146100b157806349c2a1a6146100ee578063c7f758a81461010f578063c9d27afe14610122578063da35c66414610137575b5f80fd5b610091610072366004610391565b600160208190525f918252604090912080549181015460029091015483565b604080519384526020840192909252908201526060015b60405180910390f35b6100de6100bf3660046103a8565b600260209081525f928352604080842090915290825290205460ff1681565b60405190151581526020016100a8565b6101016100fc3660046103f5565b61013f565b6040519081526020016100a8565b61009161011d366004610391565b6101b9565b6101356101303660046104a8565b610231565b005b6101015f5481565b5f8054825160208085019190912082845260019182905260408420556101669082906104cf565b5f908155818152600160205260409081902054905182917fb1e570e4094a5f87a5572e3e718941fb3822dd7fdc7a5d6d6d0d905b6c524271916101ab91815260200190565b60405180910390a292915050565b5f805f8054841061020b5760405162461bcd60e51b8152602060048201526017602482015276141c9bdc1bdcd85b08191bd95cc81b9bdd08195e1a5cdd604a1b60448201526064015b60405180910390fd5b5050505f8181526001602081905260409091208054918101546002909101549193909250565b5f54821061027b5760405162461bcd60e51b8152602060048201526017602482015276141c9bdc1bdcd85b08191bd95cc81b9bdd08195e1a5cdd604a1b6044820152606401610202565b5f82815260026020908152604080832033845290915290205460ff16156102d45760405162461bcd60e51b815260206004820152600d60248201526c105b1c9958591e481d9bdd1959609a1b6044820152606401610202565b5f8281526002602090815260408083203384529091529020805460ff19166001179055801561032b576001805f8481526020019081526020015f206001015f82825461032091906104cf565b909155506103549050565b6001805f8481526020019081526020015f206002015f82825461034e91906104cf565b90915550505b6040518115158152339083907fe71fcdac32df1877c1700e7bda2a03157e20993363a28fc35ac495cefc76e4d49060200160405180910390a35050565b5f602082840312156103a1575f80fd5b5035919050565b5f80604083850312156103b9575f80fd5b8235915060208301356001600160a01b03811681146103d6575f80fd5b809150509250929050565b634e487b7160e01b5f52604160045260245ffd5b5f60208284031215610405575f80fd5b813567ffffffffffffffff81111561041b575f80fd5b8201601f8101841361042b575f80fd5b803567ffffffffffffffff811115610445576104456103e1565b604051601f8201601f19908116603f0116810167ffffffffffffffff81118282101715610474576104746103e1565b60405281815282820160200186101561048b575f80fd5b816020840160208301375f91810160200191909152949350505050565b5f80604083850312156104b9575f80fd5b82359150602083013580151581146103d6575f80fd5b808201808211156104ee57634e487b7160e01b5f52601160045260245ffd5b9291505056fea2646970667358221220f3fd7b44fea17aed2b4c0dadc3b0f06673c0aa8aeb37ef7ee4cb714c7f17dd9d64736f6c634300081a0033" + + +## Setup: create 10 proposals (IDs 0-9) from admin +[[setup]] +kind = "create_proposal_0" +to = "{SimpleGovernance}" +signature = "function createProposal(string memory description) external returns (uint256)" +args = ["Proposal 0: Increase staking rewards"] + +[[setup]] +kind = "create_proposal_1" +to = "{SimpleGovernance}" +signature = "function createProposal(string memory description) external returns (uint256)" +args = ["Proposal 1: Reduce validator bond"] + +[[setup]] +kind = "create_proposal_2" +to = "{SimpleGovernance}" +signature = "function createProposal(string memory description) external returns (uint256)" +args = ["Proposal 2: Upgrade protocol to v2"] + +[[setup]] +kind = "create_proposal_3" +to = "{SimpleGovernance}" +signature = "function createProposal(string memory description) external returns (uint256)" +args = ["Proposal 3: Fund ecosystem grants"] + +[[setup]] +kind = "create_proposal_4" +to = "{SimpleGovernance}" +signature = "function createProposal(string memory description) external returns (uint256)" +args = ["Proposal 4: Adjust fee parameters"] + +[[setup]] +kind = "create_proposal_5" +to = "{SimpleGovernance}" +signature = "function createProposal(string memory description) external returns (uint256)" +args = ["Proposal 5: Add new oracle provider"] + +[[setup]] +kind = "create_proposal_6" +to = "{SimpleGovernance}" +signature = "function createProposal(string memory description) external returns (uint256)" +args = ["Proposal 6: Modify governance quorum"] + +[[setup]] +kind = "create_proposal_7" +to = "{SimpleGovernance}" +signature = "function createProposal(string memory description) external returns (uint256)" +args = ["Proposal 7: Treasury diversification"] + +[[setup]] +kind = "create_proposal_8" +to = "{SimpleGovernance}" +signature = "function createProposal(string memory description) external returns (uint256)" +args = ["Proposal 8: Enable cross-chain bridge"] + +[[setup]] +kind = "create_proposal_9" +to = "{SimpleGovernance}" +signature = "function createProposal(string memory description) external returns (uint256)" +args = ["Proposal 9: Update token emission schedule"] + + +## Spam: create new proposals (ongoing proposal creation load) +[[spam]] +[spam.tx] +kind = "create_proposal" +to = "{SimpleGovernance}" +from_pool = "proposers" +signature = "function createProposal(string memory description) external returns (uint256)" +args = ["Spam proposal: stress test governance"] + +## Spam: vote on existing proposals (IDs 0-9) +# Votes may revert if the sender has already voted on that proposal +[[spam]] +[spam.tx] +kind = "cast_vote" +to = "{SimpleGovernance}" +from_pool = "voters" +signature = "function vote(uint256 proposalId, bool support) external" +args = ["0", "true"] +gas_limit = 120000 +fuzz = [ + { param = "proposalId", min = "0", max = "9" }, +] diff --git a/scenarios/lending.toml b/scenarios/lending.toml new file mode 100644 index 00000000..5e907652 --- /dev/null +++ b/scenarios/lending.toml @@ -0,0 +1,138 @@ +# Simple Lending Protocol spammer scenario +# +# Deploys two ERC20 tokens (CollateralToken & BorrowToken) and a SimpleLending pool. +# Spammers deposit collateral, borrow against it, and repay loans. +# This creates realistic DeFi gas patterns: multiple storage reads/writes, balance checks, +# collateral ratio calculations, and token transfers. +# +# Source: /tmp/lending.sol (Solidity 0.8.26, optimized 200 runs) + +[env] +initialSupply = "1000000000000000000000000000" + +### Deploy contracts ########################################################### + +[[create]] +name = "CollateralToken" +# LendingToken("CollateralToken", initialSupply) +bytecode = "0x60806040526002805460ff1916601217905534801561001c575f80fd5b50604051610a24380380610a2483398101604081905261003b916100b7565b5f61004683826101ef565b50600161005383826101ef565b506003819055335f818152600460209081526040808320859055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a350506102a9565b634e487b7160e01b5f52604160045260245ffd5b5f80604083850312156100c8575f80fd5b82516001600160401b038111156100dd575f80fd5b8301601f810185136100ed575f80fd5b80516001600160401b03811115610106576101066100a3565b604051601f8201601f19908116603f011681016001600160401b0381118282101715610134576101346100a3565b60405281815282820160200187101561014b575f80fd5b8160208401602083015e5f60209282018301529401519395939450505050565b600181811c9082168061017f57607f821691505b60208210810361019d57634e487b7160e01b5f52602260045260245ffd5b50919050565b601f8211156101ea57805f5260205f20601f840160051c810160208510156101c85750805b601f840160051c820191505b818110156101e7575f81556001016101d4565b50505b505050565b81516001600160401b03811115610208576102086100a3565b61021c81610216845461016b565b846101a3565b6020601f82116001811461024e575f83156102375750848201515b5f19600385901b1c1916600184901b1784556101e7565b5f84815260208120601f198516915b8281101561027d578785015182556020948501946001909201910161025d565b508482101561029a57868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b61076e806102b65f395ff3fe608060405234801561000f575f80fd5b506004361061009b575f3560e01c806340c10f191161006357806340c10f191461012957806370a082311461013e57806395d89b411461015d578063a9059cbb14610165578063dd62ed3e14610178575f80fd5b806306fdde031461009f578063095ea7b3146100bd57806318160ddd146100e057806323b872dd146100f7578063313ce5671461010a575b5f80fd5b6100a76101a2565b6040516100b491906105c3565b60405180910390f35b6100d06100cb366004610613565b61022d565b60405190151581526020016100b4565b6100e960035481565b6040519081526020016100b4565b6100d061010536600461063b565b610299565b6002546101179060ff1681565b60405160ff90911681526020016100b4565b61013c610137366004610613565b61044f565b005b6100e961014c366004610675565b60046020525f908152604090205481565b6100a76104d5565b6100d0610173366004610613565b6104e2565b6100e9610186366004610695565b600560209081525f928352604080842090915290825290205481565b5f80546101ae906106c6565b80601f01602080910402602001604051908101604052809291908181526020018280546101da906106c6565b80156102255780601f106101fc57610100808354040283529160200191610225565b820191905f5260205f20905b81548152906001019060200180831161020857829003601f168201915b505050505081565b335f8181526005602090815260408083206001600160a01b038716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925906102879086815260200190565b60405180910390a35060015b92915050565b6001600160a01b0383165f908152600460205260408120548211156102fc5760405162461bcd60e51b8152602060048201526014602482015273696e73756666696369656e742062616c616e636560601b60448201526064015b60405180910390fd5b6001600160a01b0384165f9081526005602090815260408083203384529091529020548211156103675760405162461bcd60e51b81526020600482015260166024820152751a5b9cdd59999a58d95b9d081859db1b1b5a5b9d195960521b60448201526064016102f3565b6001600160a01b0384165f90815260056020908152604080832033845290915281208054849290610399908490610712565b90915550506001600160a01b0384165f90815260046020526040812080548492906103c5908490610712565b90915550506001600160a01b0383165f90815260046020526040812080548492906103f1908490610725565b92505081905550826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161043d91815260200190565b60405180910390a35060019392505050565b8060035f8282546104609190610725565b90915550506001600160a01b0382165f908152600460205260408120805483929061048c908490610725565b90915550506040518181526001600160a01b038316905f907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b600180546101ae906106c6565b335f908152600460205260408120548211156105375760405162461bcd60e51b8152602060048201526014602482015273696e73756666696369656e742062616c616e636560601b60448201526064016102f3565b335f9081526004602052604081208054849290610555908490610712565b90915550506001600160a01b0383165f9081526004602052604081208054849290610581908490610725565b90915550506040518281526001600160a01b0384169033907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602001610287565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f83011684010191505092915050565b80356001600160a01b038116811461060e575f80fd5b919050565b5f8060408385031215610624575f80fd5b61062d836105f8565b946020939093013593505050565b5f805f6060848603121561064d575f80fd5b610656846105f8565b9250610664602085016105f8565b929592945050506040919091013590565b5f60208284031215610685575f80fd5b61068e826105f8565b9392505050565b5f80604083850312156106a6575f80fd5b6106af836105f8565b91506106bd602084016105f8565b90509250929050565b600181811c908216806106da57607f821691505b6020821081036106f857634e487b7160e01b5f52602260045260245ffd5b50919050565b634e487b7160e01b5f52601160045260245ffd5b81810381811115610293576102936106fe565b80820180821115610293576102936106fe56fea26469706673582212203c8b78b27fb72ecdf4e0088b7e770df54bd9b5da30f2dd7f1dfb130f7cebd40364736f6c634300081a0033" +signature = "(string memory name_, uint256 initialSupply)" +args = ["CollateralToken", "{initialSupply}"] + +[[create]] +name = "BorrowToken" +# LendingToken("BorrowToken", initialSupply) +bytecode = "0x60806040526002805460ff1916601217905534801561001c575f80fd5b50604051610a24380380610a2483398101604081905261003b916100b7565b5f61004683826101ef565b50600161005383826101ef565b506003819055335f818152600460209081526040808320859055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a350506102a9565b634e487b7160e01b5f52604160045260245ffd5b5f80604083850312156100c8575f80fd5b82516001600160401b038111156100dd575f80fd5b8301601f810185136100ed575f80fd5b80516001600160401b03811115610106576101066100a3565b604051601f8201601f19908116603f011681016001600160401b0381118282101715610134576101346100a3565b60405281815282820160200187101561014b575f80fd5b8160208401602083015e5f60209282018301529401519395939450505050565b600181811c9082168061017f57607f821691505b60208210810361019d57634e487b7160e01b5f52602260045260245ffd5b50919050565b601f8211156101ea57805f5260205f20601f840160051c810160208510156101c85750805b601f840160051c820191505b818110156101e7575f81556001016101d4565b50505b505050565b81516001600160401b03811115610208576102086100a3565b61021c81610216845461016b565b846101a3565b6020601f82116001811461024e575f83156102375750848201515b5f19600385901b1c1916600184901b1784556101e7565b5f84815260208120601f198516915b8281101561027d578785015182556020948501946001909201910161025d565b508482101561029a57868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b61076e806102b65f395ff3fe608060405234801561000f575f80fd5b506004361061009b575f3560e01c806340c10f191161006357806340c10f191461012957806370a082311461013e57806395d89b411461015d578063a9059cbb14610165578063dd62ed3e14610178575f80fd5b806306fdde031461009f578063095ea7b3146100bd57806318160ddd146100e057806323b872dd146100f7578063313ce5671461010a575b5f80fd5b6100a76101a2565b6040516100b491906105c3565b60405180910390f35b6100d06100cb366004610613565b61022d565b60405190151581526020016100b4565b6100e960035481565b6040519081526020016100b4565b6100d061010536600461063b565b610299565b6002546101179060ff1681565b60405160ff90911681526020016100b4565b61013c610137366004610613565b61044f565b005b6100e961014c366004610675565b60046020525f908152604090205481565b6100a76104d5565b6100d0610173366004610613565b6104e2565b6100e9610186366004610695565b600560209081525f928352604080842090915290825290205481565b5f80546101ae906106c6565b80601f01602080910402602001604051908101604052809291908181526020018280546101da906106c6565b80156102255780601f106101fc57610100808354040283529160200191610225565b820191905f5260205f20905b81548152906001019060200180831161020857829003601f168201915b505050505081565b335f8181526005602090815260408083206001600160a01b038716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925906102879086815260200190565b60405180910390a35060015b92915050565b6001600160a01b0383165f908152600460205260408120548211156102fc5760405162461bcd60e51b8152602060048201526014602482015273696e73756666696369656e742062616c616e636560601b60448201526064015b60405180910390fd5b6001600160a01b0384165f9081526005602090815260408083203384529091529020548211156103675760405162461bcd60e51b81526020600482015260166024820152751a5b9cdd59999a58d95b9d081859db1b1b5a5b9d195960521b60448201526064016102f3565b6001600160a01b0384165f90815260056020908152604080832033845290915281208054849290610399908490610712565b90915550506001600160a01b0384165f90815260046020526040812080548492906103c5908490610712565b90915550506001600160a01b0383165f90815260046020526040812080548492906103f1908490610725565b92505081905550826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161043d91815260200190565b60405180910390a35060019392505050565b8060035f8282546104609190610725565b90915550506001600160a01b0382165f908152600460205260408120805483929061048c908490610725565b90915550506040518181526001600160a01b038316905f907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b600180546101ae906106c6565b335f908152600460205260408120548211156105375760405162461bcd60e51b8152602060048201526014602482015273696e73756666696369656e742062616c616e636560601b60448201526064016102f3565b335f9081526004602052604081208054849290610555908490610712565b90915550506001600160a01b0383165f9081526004602052604081208054849290610581908490610725565b90915550506040518281526001600160a01b0384169033907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602001610287565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f83011684010191505092915050565b80356001600160a01b038116811461060e575f80fd5b919050565b5f8060408385031215610624575f80fd5b61062d836105f8565b946020939093013593505050565b5f805f6060848603121561064d575f80fd5b610656846105f8565b9250610664602085016105f8565b929592945050506040919091013590565b5f60208284031215610685575f80fd5b61068e826105f8565b9392505050565b5f80604083850312156106a6575f80fd5b6106af836105f8565b91506106bd602084016105f8565b90509250929050565b600181811c908216806106da57607f821691505b6020821081036106f857634e487b7160e01b5f52602260045260245ffd5b50919050565b634e487b7160e01b5f52601160045260245ffd5b81810381811115610293576102936106fe565b80820180821115610293576102936106fe56fea26469706673582212203c8b78b27fb72ecdf4e0088b7e770df54bd9b5da30f2dd7f1dfb130f7cebd40364736f6c634300081a0033" +signature = "(string memory name_, uint256 initialSupply)" +args = ["BorrowToken", "{initialSupply}"] + +[[create]] +name = "SimpleLending" +# SimpleLending(collateralToken, borrowToken) +bytecode = "0x6080604052348015600e575f80fd5b506040516109c43803806109c4833981016040819052602b916074565b5f80546001600160a01b039384166001600160a01b0319918216179091556001805492909316911617905560a0565b80516001600160a01b0381168114606f575f80fd5b919050565b5f80604083850312156084575f80fd5b608b83605a565b9150609760208401605a565b90509250929050565b610917806100ad5f395ff3fe608060405234801561000f575f80fd5b50600436106100b1575f3560e01c8063b2016bd41161006e578063b2016bd414610162578063bad4a01f14610174578063c5ebeaec14610187578063d9e69a051461019a578063f19562b6146101a2578063ff50abdc146101aa575f80fd5b806329bc969d146100b5578063371fd8e6146100e7578063456dc17a146100fc5780634c19386c146101275780636112fe2e1461013057806394e1373c14610143575b5f80fd5b6100d46100c33660046107e4565b60026020525f908152604090205481565b6040519081526020015b60405180910390f35b6100fa6100f5366004610811565b6101b3565b005b60015461010f906001600160a01b031681565b6040516001600160a01b0390911681526020016100de565b6100d460055481565b6100fa61013e366004610811565b61031b565b6100d46101513660046107e4565b60036020525f908152604090205481565b5f5461010f906001600160a01b031681565b6100fa610182366004610811565b6104aa565b6100fa610195366004610811565b6105ae565b6100d4609681565b6100d4606481565b6100d460045481565b5f81116101db5760405162461bcd60e51b81526004016101d290610828565b60405180910390fd5b335f9081526003602052604090205481111561022e5760405162461bcd60e51b81526020600482015260126024820152711c995c185e48195e18d959591cc81919589d60721b60448201526064016101d2565b6001546040516323b872dd60e01b8152336004820152306024820152604481018390526001600160a01b03909116906323b872dd906064016020604051808303815f875af1158015610282573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906102a69190610854565b50335f90815260036020526040812080548392906102c5908490610887565b925050819055508060055f8282546102dd9190610887565b909155505060405181815233907f5c16de4f8b59bd9caf0f49a545f25819a895ed223294290b408242e72a594231906020015b60405180910390a250565b5f811161033a5760405162461bcd60e51b81526004016101d290610828565b335f90815260026020526040812054610354908390610887565b335f90815260036020526040902054909150610372906096906108a0565b61037d6064836108a0565b10156103d75760405162461bcd60e51b8152602060048201526024808201527f756e646572636f6c6c61746572616c697a656420616674657220776974686472604482015263185dd85b60e21b60648201526084016101d2565b335f908152600260205260408120829055600480548492906103fa908490610887565b90915550505f5460405163a9059cbb60e01b8152336004820152602481018490526001600160a01b039091169063a9059cbb906044016020604051808303815f875af115801561044c573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906104709190610854565b5060405182815233907f884edad9ce6fa2440d8a54cc123490eb96d2768479d49ff9c7366125a94243649060200160405180910390a25050565b5f81116104c95760405162461bcd60e51b81526004016101d290610828565b5f546040516323b872dd60e01b8152336004820152306024820152604481018390526001600160a01b03909116906323b872dd906064016020604051808303815f875af115801561051c573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906105409190610854565b50335f908152600260205260408120805483929061055f9084906108b7565b925050819055508060045f82825461057791906108b7565b909155505060405181815233907fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c90602001610310565b5f81116105cd5760405162461bcd60e51b81526004016101d290610828565b335f908152600360205260408120546105e79083906108b7565b90506105f46096826108a0565b335f9081526002602052604090205461060f906064906108a0565b10156106535760405162461bcd60e51b81526020600482015260136024820152721d5b99195c98dbdb1b185d195c985b1a5e9959606a1b60448201526064016101d2565b6001546040516370a0823160e01b81523060048201525f916001600160a01b0316906370a0823190602401602060405180830381865afa158015610699573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906106bd91906108ca565b90508281101561070f5760405162461bcd60e51b815260206004820152601b60248201527f696e73756666696369656e7420706f6f6c206c6971756964697479000000000060448201526064016102f3565b335f908152600360205260408120839055600580548592906107329084906108b7565b909155505060015460405163a9059cbb60e01b8152336004820152602481018590526001600160a01b039091169063a9059cbb906044016020604051808303815f875af1158015610785573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906107a99190610854565b5060405183815233907fcbc04eca7e9da35cb1393a6135a199ca52e450d5e9251cbd99f7847d33a367509060200160405180910390a2505050565b5f602082840312156107f4575f80fd5b81356001600160a01b038116811461080a575f80fd5b9392505050565b5f60208284031215610821575f80fd5b5035919050565b6020808252601290820152710616d6f756e74206d757374206265203e20360741b604082015260600190565b5f60208284031215610864575f80fd5b8151801515811461080a575f80fd5b634e487b7160e01b5f52601160045260245ffd5b8181038181111561089a5761089a610873565b92915050565b808202811582820484141761089a5761089a610873565b8082018082111561089a5761089a610873565b5f602082840312156108da575f80fd5b505191905056fea2646970667358221220f700a8c4fdf59e2b5144aaf6122d1151b7132c3ab61bd84204f1a6055bbf13e264736f6c634300081a0033" +signature = "(address collateralToken_, address borrowToken_)" +args = ["{CollateralToken}", "{BorrowToken}"] + +### Setup: Admin funds the lending pool ######################################## + +# Mint extra CollateralTokens for the admin (used to fund spammers) +[[setup]] +kind = "admin_mint_collateral" +to = "{CollateralToken}" +signature = "mint(address to, uint256 amount)" +args = ["{_sender}", "500000000000000000000000000"] + +# Mint extra BorrowTokens for the admin +[[setup]] +kind = "admin_mint_borrow" +to = "{BorrowToken}" +signature = "mint(address to, uint256 amount)" +args = ["{_sender}", "500000000000000000000000000"] + +# Transfer BorrowTokens to lending pool so borrowers can draw from it +[[setup]] +kind = "admin_fund_lending_pool" +to = "{BorrowToken}" +signature = "transfer(address to, uint256 amount) returns (bool)" +args = ["{SimpleLending}", "200000000000000000000000000"] + +### Setup: Prepare each spammer account ######################################## + +# Mint CollateralTokens for each spammer +[[setup]] +kind = "mint_collateral_for_spammer" +to = "{CollateralToken}" +signature = "mint(address to, uint256 amount)" +args = ["{_sender}", "10000000000000000000000"] +from_pool = "spammer" +for_all_accounts = true + +# Approve lending contract to spend spammer's CollateralTokens +[[setup]] +kind = "approve_collateral_for_spammer" +to = "{CollateralToken}" +signature = "approve(address spender, uint256 amount) returns (bool)" +args = ["{SimpleLending}", "115792089237316195423570985008687907853269984665640564039457584007913129639935"] +from_pool = "spammer" +for_all_accounts = true + +# Approve lending contract to spend spammer's BorrowTokens (for repay) +[[setup]] +kind = "approve_borrow_for_spammer" +to = "{BorrowToken}" +signature = "approve(address spender, uint256 amount) returns (bool)" +args = ["{SimpleLending}", "115792089237316195423570985008687907853269984665640564039457584007913129639935"] +from_pool = "spammer" +for_all_accounts = true + +# Deposit initial collateral for each spammer +[[setup]] +kind = "deposit_initial_collateral" +to = "{SimpleLending}" +signature = "depositCollateral(uint256 amount)" +args = ["5000000000000000000000"] +from_pool = "spammer" +for_all_accounts = true +gas_limit = 200000 + +### Spam: Lending operations ################################################### + +# Spam pattern 1: Deposit more collateral (fuzz amount 1e15 to 1e17) +[[spam]] +[spam.tx] +kind = "deposit_collateral" +to = "{SimpleLending}" +from_pool = "spammer" +signature = "depositCollateral(uint256 amount)" +args = ["50000000000000000"] +fuzz = [ + { param = "amount", min = "1000000000000000", max = "100000000000000000" }, +] + +# Spam pattern 2: Borrow against collateral (fuzz amount 1e14 to 1e16) +# May revert if undercollateralized, so gas_limit is set to skip estimation +[[spam]] +[spam.tx] +kind = "borrow" +to = "{SimpleLending}" +from_pool = "spammer" +signature = "borrow(uint256 amount)" +args = ["5000000000000000"] +gas_limit = 300000 +fuzz = [ + { param = "amount", min = "100000000000000", max = "10000000000000000" }, +] + +# Spam pattern 3: Repay borrowed tokens (fuzz amount 1e13 to 1e15) +# May revert if no outstanding debt, so gas_limit is set to skip estimation +[[spam]] +[spam.tx] +kind = "repay" +to = "{SimpleLending}" +from_pool = "spammer" +signature = "repay(uint256 amount)" +args = ["500000000000000"] +gas_limit = 300000 +fuzz = [ + { param = "amount", min = "10000000000000", max = "1000000000000000" }, +] diff --git a/scenarios/merkleAirdrop.toml b/scenarios/merkleAirdrop.toml new file mode 100644 index 00000000..f62e85cc --- /dev/null +++ b/scenarios/merkleAirdrop.toml @@ -0,0 +1,56 @@ +# ============================================================ +# Merkle Tree Airdrop Claim - Keccak256 Compute Stress Test +# ============================================================ +# Source: /tmp/merkle_airdrop.sol (AirdropToken + MockMerkleAirdrop) +# Gas profile: keccak256-heavy proof verification loop, +# bitmap storage writes, ERC20 token transfers +# ============================================================ + +[env] +initialSupply = "1000000000000000000000000000" +airdropFundAmount = "500000000000000000000000000" + +### Deploy AirdropToken with initial supply + +[[create]] +name = "AirdropToken" +signature = "(uint256 initialSupply)" +args = ["{initialSupply}"] +bytecode = "0x60c0604052600c60809081526b20b4b9323937b82a37b5b2b760a11b60a0525f9061002a9082610170565b5060408051808201909152600381526210511560ea1b60208201526001906100529082610170565b506002805460ff1916601217905534801561006b575f80fd5b506040516109bc3803806109bc83398101604081905261008a9161022a565b6003819055335f818152600460209081526040808320859055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a350610241565b634e487b7160e01b5f52604160045260245ffd5b600181811c9082168061010057607f821691505b60208210810361011e57634e487b7160e01b5f52602260045260245ffd5b50919050565b601f82111561016b57805f5260205f20601f840160051c810160208510156101495750805b601f840160051c820191505b81811015610168575f8155600101610155565b50505b505050565b81516001600160401b03811115610189576101896100d8565b61019d8161019784546100ec565b84610124565b6020601f8211600181146101cf575f83156101b85750848201515b5f19600385901b1c1916600184901b178455610168565b5f84815260208120601f198516915b828110156101fe57878501518255602094850194600190920191016101de565b508482101561021b57868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b5f6020828403121561023a575f80fd5b5051919050565b61076e8061024e5f395ff3fe608060405234801561000f575f80fd5b506004361061009b575f3560e01c806340c10f191161006357806340c10f191461012957806370a082311461013e57806395d89b411461015d578063a9059cbb14610165578063dd62ed3e14610178575f80fd5b806306fdde031461009f578063095ea7b3146100bd57806318160ddd146100e057806323b872dd146100f7578063313ce5671461010a575b5f80fd5b6100a76101a2565b6040516100b491906105c3565b60405180910390f35b6100d06100cb366004610613565b61022d565b60405190151581526020016100b4565b6100e960035481565b6040519081526020016100b4565b6100d061010536600461063b565b610299565b6002546101179060ff1681565b60405160ff90911681526020016100b4565b61013c610137366004610613565b61044f565b005b6100e961014c366004610675565b60046020525f908152604090205481565b6100a76104d5565b6100d0610173366004610613565b6104e2565b6100e9610186366004610695565b600560209081525f928352604080842090915290825290205481565b5f80546101ae906106c6565b80601f01602080910402602001604051908101604052809291908181526020018280546101da906106c6565b80156102255780601f106101fc57610100808354040283529160200191610225565b820191905f5260205f20905b81548152906001019060200180831161020857829003601f168201915b505050505081565b335f8181526005602090815260408083206001600160a01b038716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925906102879086815260200190565b60405180910390a35060015b92915050565b6001600160a01b0383165f908152600460205260408120548211156102fc5760405162461bcd60e51b8152602060048201526014602482015273696e73756666696369656e742062616c616e636560601b60448201526064015b60405180910390fd5b6001600160a01b0384165f9081526005602090815260408083203384529091529020548211156103675760405162461bcd60e51b8152602060048201526016602482015275696e73756666696369656e7420616c6c6f77616e636560501b60448201526064016102f3565b6001600160a01b0384165f90815260056020908152604080832033845290915281208054849290610399908490610712565b90915550506001600160a01b0384165f90815260046020526040812080548492906103c5908490610712565b90915550506001600160a01b0383165f90815260046020526040812080548492906103f1908490610725565b92505081905550826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161043d91815260200190565b60405180910390a35060019392505050565b8060035f8282546104609190610725565b90915550506001600160a01b0382165f908152600460205260408120805483929061048c908490610725565b90915550506040518181526001600160a01b038316905f907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b600180546101ae906106c6565b335f908152600460205260408120548211156105375760405162461bcd60e51b8152602060048201526014602482015273696e73756666696369656e742062616c616e636560601b60448201526064016102f3565b335f9081526004602052604081208054849290610555908490610712565b90915550506001600160a01b0383165f9081526004602052604081208054849290610581908490610725565b90915550506040518281526001600160a01b0384169033907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602001610287565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f83011684010191505092915050565b80356001600160a01b038116811461060e575f80fd5b919050565b5f8060408385031215610624575f80fd5b61062d836105f8565b946020939093013593505050565b5f805f6060848603121561064d575f80fd5b610656846105f8565b9250610664602085016105f8565b929592945050506040919091013590565b5f60208284031215610685575f80fd5b61068e826105f8565b9392505050565b5f80604083850312156106a6575f80fd5b6106af836105f8565b91506106bd602084016105f8565b90509250929050565b600181811c908216806106da57607f821691505b6020821081036106f857634e487b7160e01b5f52602260045260245ffd5b50919050565b634e487b7160e01b5f52601160045260245ffd5b81810381811115610293576102936106fe565b80820180821115610293576102936106fe56fea26469706673582212207cb59ae0c509afdbde4e0120cd1357284c6b255339d3298c4e219166baefa7f664736f6c634300081a0033" + +### Deploy MockMerkleAirdrop with (token address, proofDepth) +### proofDepth is stored but the actual numHashes is passed per-call for fuzzing + +[[create]] +name = "MockMerkleAirdrop" +signature = "(address token_, uint256 proofDepth_)" +args = ["{AirdropToken}", "20"] +bytecode = "0x6080604052348015600e575f80fd5b506040516104fd3803806104fd833981016040819052602b916052565b5f80546001600160a01b0319166001600160a01b0393909316929092179091556001556087565b5f80604083850312156062575f80fd5b82516001600160a01b03811681146077575f80fd5b6020939093015192949293505050565b610469806100945f395ff3fe608060405234801561000f575f80fd5b5060043610610055575f3560e01c80639e34070f14610059578063b271d25314610081578063ee25560b14610098578063efa9a9be146100b7578063fc0c546a146100cc575b5f80fd5b61006c6100673660046103a3565b6100f6565b60405190151581526020015b60405180910390f35b61008a60015481565b604051908152602001610078565b61008a6100a63660046103a3565b60026020525f908152604090205481565b6100ca6100c53660046103ba565b610133565b005b5f546100de906001600160a01b031681565b6040516001600160a01b039091168152602001610078565b5f80610104610100846103f7565b90505f6101136101008561040a565b5f9283526002602052604090922054600190921b90911615159392505050565b61013c836100f6565b156101805760405162461bcd60e51b815260206004820152600f60248201526e185b1c9958591e4818db185a5b5959608a1b60448201526064015b60405180910390fd5b6040805160208082018690523360601b6bffffffffffffffffffffffff191682840152605480830186905283518084039091018152607490920190925280519101205f5b8281101561020257604080516020810184905290810182905260600160408051601f19818403018152919052805160209091012091506001016101c4565b50806102405760405162461bcd60e51b815260206004820152600d60248201526c34b73b30b634b210383937b7b360991b6044820152606401610177565b61024984610368565b5f8054604051336024820152604481018690526001600160a01b039091169060640160408051601f198184030181529181526020820180516001600160e01b031663a9059cbb60e01b179052516102a0919061041d565b5f604051808303815f865af19150503d805f81146102d9576040519150601f19603f3d011682016040523d82523d5f602084013e6102de565b606091505b50509050806103215760405162461bcd60e51b815260206004820152600f60248201526e1d1c985b9cd9995c8819985a5b1959608a1b6044820152606401610177565b604080518681523360208201529081018590527f4ec90e965519d92681267467f775ada5bd214aa92c0dc93d90a5e880ce9ed0269060600160405180910390a15050505050565b5f610375610100836103f7565b90505f6103846101008461040a565b5f928352600260205260409092208054600190931b9092179091555050565b5f602082840312156103b3575f80fd5b5035919050565b5f805f606084860312156103cc575f80fd5b505081359360208301359350604090920135919050565b634e487b7160e01b5f52601260045260245ffd5b5f82610405576104056103e3565b500490565b5f82610418576104186103e3565b500690565b5f82518060208501845e5f92019182525091905056fea2646970667358221220a2e074e8b2ab4362e9298868ffe8667a3c1c786042386a006ad1f6d51d7b69db64736f6c634300081a0033" + +### Setup: mint tokens to the airdrop contract to fund claims + +[[setup]] +kind = "fund_airdrop" +to = "{AirdropToken}" +signature = "mint(address to, uint256 amount)" +args = ["{MockMerkleAirdrop}", "{airdropFundAmount}"] + +### Spam: claim airdrop with fuzzed index, amount, and numHashes +### - index is fuzzed across a wide range so claimed bitmap rarely collides +### - amount is fuzzed from 0.1 to 10 tokens +### - numHashes is fuzzed from 10 to 30 (simulates trees of 1K to 1B leaves) +### - May revert if the same index is claimed twice (bitmap collision) + +[[spam]] +[spam.tx] +kind = "claim" +to = "{MockMerkleAirdrop}" +from_pool = "spammer" +signature = "claim(uint256 index, uint256 amount, uint256 numHashes)" +args = ["1", "1000000000000000000", "20"] +gas_limit = 300000 +fuzz = [ + { param = "index", min = "0", max = "1000000" }, + { param = "amount", min = "100000000000000000", max = "10000000000000000000" }, + { param = "numHashes", min = "10", max = "30" }, +] diff --git a/scenarios/mevSandwich.toml b/scenarios/mevSandwich.toml new file mode 100644 index 00000000..2d3b6daf --- /dev/null +++ b/scenarios/mevSandwich.toml @@ -0,0 +1,194 @@ +# MEV Sandwich Attack scenario +# +# Simulates MEV sandwich attacks, which are >1 per block on mainnet. +# Pattern: frontrun tx (buy) -> victim tx (swap) -> backrun tx (sell). +# Tests bundle ordering and multi-tx atomic patterns. +# +# Contracts: +# - SandwichToken: Minimal ERC20 with public mint +# - SandwichPool: Simple constant product AMM (x*y=k) with 0.3% fee +# - SandwichBot: MEV bot that frontruns and backruns victim swaps +# +# source: /tmp/sandwich.sol +# compiled with: solc --bin --optimize --optimize-runs 200 /tmp/sandwich.sol + +[env] +initialSupply = "1000000000000000000000000000" +liquidityAmount = "500000000000000000000000" +botFunds = "100000000000000000000000" +spammerMintAmount = "50000000000000000000000" + + +### Deploy contracts ########################################################### + +[[create]] +name = "TokenA" +signature = "(uint256 initialSupply)" +args = ["{initialSupply}"] +bytecode = "0x608060405234801561000f575f80fd5b506040516108b73803806108b783398101604081905261002e916100d6565b60408051808201909152600d81526c29b0b7323bb4b1b42a37b5b2b760991b60208201525f9061005e9082610185565b5060408051808201909152600481526314d0539160e21b60208201526001906100879082610185565b506002819055335f818152600360209081526040808320859055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35061023f565b5f602082840312156100e6575f80fd5b5051919050565b634e487b7160e01b5f52604160045260245ffd5b600181811c9082168061011557607f821691505b60208210810361013357634e487b7160e01b5f52602260045260245ffd5b50919050565b601f82111561018057805f5260205f20601f840160051c8101602085101561015e5750805b601f840160051c820191505b8181101561017d575f815560010161016a565b50505b505050565b81516001600160401b0381111561019e5761019e6100ed565b6101b2816101ac8454610101565b84610139565b6020601f8211600181146101e4575f83156101cd5750848201515b5f19600385901b1c1916600184901b17845561017d565b5f84815260208120601f198516915b8281101561021357878501518255602094850194600190920191016101f3565b508482101561023057868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b61066b8061024c5f395ff3fe608060405234801561000f575f80fd5b506004361061009b575f3560e01c806340c10f191161006357806340c10f191461012457806370a082311461013957806395d89b4114610158578063a9059cbb14610160578063dd62ed3e14610173575f80fd5b806306fdde031461009f578063095ea7b3146100bd57806318160ddd146100e057806323b872dd146100f7578063313ce5671461010a575b5f80fd5b6100a761019d565b6040516100b491906104c0565b60405180910390f35b6100d06100cb366004610510565b610228565b60405190151581526020016100b4565b6100e960025481565b6040519081526020016100b4565b6100d0610105366004610538565b610294565b610112601281565b60405160ff90911681526020016100b4565b610137610132366004610510565b61039f565b005b6100e9610147366004610572565b60036020525f908152604090205481565b6100a7610425565b6100d061016e366004610510565b610432565b6100e9610181366004610592565b600460209081525f928352604080842090915290825290205481565b5f80546101a9906105c3565b80601f01602080910402602001604051908101604052809291908181526020018280546101d5906105c3565b80156102205780601f106101f757610100808354040283529160200191610220565b820191905f5260205f20905b81548152906001019060200180831161020357829003601f168201915b505050505081565b335f8181526004602090815260408083206001600160a01b038716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925906102829086815260200190565b60405180910390a35060015b92915050565b6001600160a01b0383165f9081526004602090815260408083203384529091528120545f1981146102ed576102c9838261060f565b6001600160a01b0386165f9081526004602090815260408083203384529091529020555b6001600160a01b0385165f908152600360205260408120805485929061031490849061060f565b90915550506001600160a01b0384165f9081526003602052604081208054859290610340908490610622565b92505081905550836001600160a01b0316856001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8560405161038c91815260200190565b60405180910390a3506001949350505050565b8060025f8282546103b09190610622565b90915550506001600160a01b0382165f90815260036020526040812080548392906103dc908490610622565b90915550506040518181526001600160a01b038316905f907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b600180546101a9906105c3565b335f9081526003602052604081208054839190839061045290849061060f565b90915550506001600160a01b0383165f908152600360205260408120805484929061047e908490610622565b90915550506040518281526001600160a01b0384169033907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602001610282565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f83011684010191505092915050565b80356001600160a01b038116811461050b575f80fd5b919050565b5f8060408385031215610521575f80fd5b61052a836104f5565b946020939093013593505050565b5f805f6060848603121561054a575f80fd5b610553846104f5565b9250610561602085016104f5565b929592945050506040919091013590565b5f60208284031215610582575f80fd5b61058b826104f5565b9392505050565b5f80604083850312156105a3575f80fd5b6105ac836104f5565b91506105ba602084016104f5565b90509250929050565b600181811c908216806105d757607f821691505b6020821081036105f557634e487b7160e01b5f52602260045260245ffd5b50919050565b634e487b7160e01b5f52601160045260245ffd5b8181038181111561028e5761028e6105fb565b8082018082111561028e5761028e6105fb56fea26469706673582212200bc0c22982a4e776b1f8bec176ec3a199a0691f37a237c8a0b33822f8d4a008064736f6c634300081a0033" + +[[create]] +name = "TokenB" +signature = "(uint256 initialSupply)" +args = ["{initialSupply}"] +bytecode = "0x608060405234801561000f575f80fd5b506040516108b73803806108b783398101604081905261002e916100d6565b60408051808201909152600d81526c29b0b7323bb4b1b42a37b5b2b760991b60208201525f9061005e9082610185565b5060408051808201909152600481526314d0539160e21b60208201526001906100879082610185565b506002819055335f818152600360209081526040808320859055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35061023f565b5f602082840312156100e6575f80fd5b5051919050565b634e487b7160e01b5f52604160045260245ffd5b600181811c9082168061011557607f821691505b60208210810361013357634e487b7160e01b5f52602260045260245ffd5b50919050565b601f82111561018057805f5260205f20601f840160051c8101602085101561015e5750805b601f840160051c820191505b8181101561017d575f815560010161016a565b50505b505050565b81516001600160401b0381111561019e5761019e6100ed565b6101b2816101ac8454610101565b84610139565b6020601f8211600181146101e4575f83156101cd5750848201515b5f19600385901b1c1916600184901b17845561017d565b5f84815260208120601f198516915b8281101561021357878501518255602094850194600190920191016101f3565b508482101561023057868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b61066b8061024c5f395ff3fe608060405234801561000f575f80fd5b506004361061009b575f3560e01c806340c10f191161006357806340c10f191461012457806370a082311461013957806395d89b4114610158578063a9059cbb14610160578063dd62ed3e14610173575f80fd5b806306fdde031461009f578063095ea7b3146100bd57806318160ddd146100e057806323b872dd146100f7578063313ce5671461010a575b5f80fd5b6100a761019d565b6040516100b491906104c0565b60405180910390f35b6100d06100cb366004610510565b610228565b60405190151581526020016100b4565b6100e960025481565b6040519081526020016100b4565b6100d0610105366004610538565b610294565b610112601281565b60405160ff90911681526020016100b4565b610137610132366004610510565b61039f565b005b6100e9610147366004610572565b60036020525f908152604090205481565b6100a7610425565b6100d061016e366004610510565b610432565b6100e9610181366004610592565b600460209081525f928352604080842090915290825290205481565b5f80546101a9906105c3565b80601f01602080910402602001604051908101604052809291908181526020018280546101d5906105c3565b80156102205780601f106101f757610100808354040283529160200191610220565b820191905f5260205f20905b81548152906001019060200180831161020357829003601f168201915b505050505081565b335f8181526004602090815260408083206001600160a01b038716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925906102829086815260200190565b60405180910390a35060015b92915050565b6001600160a01b0383165f9081526004602090815260408083203384529091528120545f1981146102ed576102c9838261060f565b6001600160a01b0386165f9081526004602090815260408083203384529091529020555b6001600160a01b0385165f908152600360205260408120805485929061031490849061060f565b90915550506001600160a01b0384165f9081526003602052604081208054859290610340908490610622565b92505081905550836001600160a01b0316856001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8560405161038c91815260200190565b60405180910390a3506001949350505050565b8060025f8282546103b09190610622565b90915550506001600160a01b0382165f90815260036020526040812080548392906103dc908490610622565b90915550506040518181526001600160a01b038316905f907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b600180546101a9906105c3565b335f9081526003602052604081208054839190839061045290849061060f565b90915550506001600160a01b0383165f908152600360205260408120805484929061047e908490610622565b90915550506040518281526001600160a01b0384169033907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602001610282565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f83011684010191505092915050565b80356001600160a01b038116811461050b575f80fd5b919050565b5f8060408385031215610521575f80fd5b61052a836104f5565b946020939093013593505050565b5f805f6060848603121561054a575f80fd5b610553846104f5565b9250610561602085016104f5565b929592945050506040919091013590565b5f60208284031215610582575f80fd5b61058b826104f5565b9392505050565b5f80604083850312156105a3575f80fd5b6105ac836104f5565b91506105ba602084016104f5565b90509250929050565b600181811c908216806105d757607f821691505b6020821081036105f557634e487b7160e01b5f52602260045260245ffd5b50919050565b634e487b7160e01b5f52601160045260245ffd5b8181038181111561028e5761028e6105fb565b8082018082111561028e5761028e6105fb56fea26469706673582212200bc0c22982a4e776b1f8bec176ec3a199a0691f37a237c8a0b33822f8d4a008064736f6c634300081a0033" + +[[create]] +name = "SandwichPool" +signature = "(address tokenA_, address tokenB_)" +args = ["{TokenA}", "{TokenB}"] +bytecode = "0x6080604052348015600e575f80fd5b506040516107bb3803806107bb833981016040819052602b916074565b5f80546001600160a01b039384166001600160a01b0319918216179091556001805492909316911617905560a0565b80516001600160a01b0381168114606f575f80fd5b919050565b5f80604083850312156084575f80fd5b608b83605a565b9150609760208401605a565b90509250929050565b61070e806100ad5f395ff3fe608060405234801561000f575f80fd5b5060043610610085575f3560e01c80639cd441da116100585780639cd441da146100fd5780639f1d0f5914610112578063ca706bcf14610125578063dc5fa6c514610138575f80fd5b80630902f1ac146100895780630fc63d10146100a957806319e36f3b146100d35780635f64b55b146100ea575b5f80fd5b600254600354604080519283526020830191909152015b60405180910390f35b5f546100bb906001600160a01b031681565b6040516001600160a01b0390911681526020016100a0565b6100dc60035481565b6040519081526020016100a0565b6001546100bb906001600160a01b031681565b61011061010b3660046105af565b610141565b005b6100dc6101203660046105ea565b61029f565b6100dc61013336600461061a565b6104f6565b6100dc60025481565b5f546040516323b872dd60e01b8152336004820152306024820152604481018490526001600160a01b03909116906323b872dd906064016020604051808303815f875af1158015610194573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906101b89190610642565b506001546040516323b872dd60e01b8152336004820152306024820152604481018390526001600160a01b03909116906323b872dd906064016020604051808303815f875af115801561020d573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906102319190610642565b508160025f828254610243919061067c565b925050819055508060035f82825461025b919061067c565b9091555050604080518381526020810183905233917fac1d76749e5447b7b16f5ab61447e1bd502f3bb4807af3b28e620d1700a6ee45910160405180910390a25050565b5f8083116102e15760405162461bcd60e51b815260206004820152600a6024820152691e995c9bc81a5b9c1d5d60b21b60448201526064015b60405180910390fd5b6102eb84846104f6565b9050818110156103285760405162461bcd60e51b8152602060048201526008602482015267736c69707061676560c01b60448201526064016102d8565b5f80546001600160a01b03908116908616036103855750600154600280546001600160a01b03909216918591905f9061036290849061067c565b925050819055508160035f82825461037a919061068f565b909155506103c49050565b505f8054600380546001600160a01b039092169286926103a690849061067c565b925050819055508160025f8282546103be919061068f565b90915550505b6040516323b872dd60e01b8152336004820152306024820152604481018590526001600160a01b038616906323b872dd906064016020604051808303815f875af1158015610414573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906104389190610642565b5060405163a9059cbb60e01b8152336004820152602481018390526001600160a01b0382169063a9059cbb906044016020604051808303815f875af1158015610483573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906104a79190610642565b5060408051858152602081018490526001600160a01b0387169133917ffa2dda1cc1b86e41239702756b13effbc1a092b5c57e3ad320fbe4f3b13fe235910160405180910390a3509392505050565b5f8082116105335760405162461bcd60e51b815260206004820152600a6024820152691e995c9bc81a5b9c1d5d60b21b60448201526064016102d8565b5f805481906001600160a01b0390811690861603610558575050600254600354610561565b50506003546002545b5f61056e856103e56106a2565b90505f61057b83836106a2565b90505f8261058b866103e86106a2565b610595919061067c565b90506105a181836106b9565b955050505050505b92915050565b5f80604083850312156105c0575f80fd5b50508035926020909101359150565b80356001600160a01b03811681146105e5575f80fd5b919050565b5f805f606084860312156105fc575f80fd5b610605846105cf565b95602085013595506040909401359392505050565b5f806040838503121561062b575f80fd5b610634836105cf565b946020939093013593505050565b5f60208284031215610652575f80fd5b81518015158114610661575f80fd5b9392505050565b634e487b7160e01b5f52601160045260245ffd5b808201808211156105a9576105a9610668565b818103818111156105a9576105a9610668565b80820281158282048414176105a9576105a9610668565b5f826106d357634e487b7160e01b5f52601260045260245ffd5b50049056fea2646970667358221220a5ae292cf18a5cfef5969550a956843d7063bb1765d97a015d77a52dd444634664736f6c634300081a0033" + +[[create]] +name = "SandwichBot" +signature = "()" +args = [] +bytecode = "0x6080604052348015600e575f80fd5b505f80546001600160a01b031916331790556103ba8061002d5f395ff3fe608060405260043610610041575f3560e01c806349df728c1461004c57806385cb02ba1461006d5780638da5cb5b1461008c578063bd39b1341461006d575f80fd5b3661004857005b5f80fd5b348015610057575f80fd5b5061006b6100663660046102f5565b6100c6565b005b348015610078575f80fd5b5061006b610087366004610315565b6101ed565b348015610097575f80fd5b505f546100aa906001600160a01b031681565b6040516001600160a01b03909116815260200160405180910390f35b5f546001600160a01b0316331461010f5760405162461bcd60e51b81526020600482015260096024820152683737ba1037bbb732b960b91b604482015260640160405180910390fd5b6040516370a0823160e01b81523060048201525f906001600160a01b038316906370a0823190602401602060405180830381865afa158015610153573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610177919061034e565b60405163a9059cbb60e01b8152336004820152602481018290529091506001600160a01b0383169063a9059cbb906044016020604051808303815f875af11580156101c4573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906101e89190610365565b505050565b60405163095ea7b360e01b81526001600160a01b0384811660048301526024820183905283169063095ea7b3906044016020604051808303815f875af1158015610239573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061025d9190610365565b50604051639f1d0f5960e01b81526001600160a01b038381166004830152602482018390525f6044830152841690639f1d0f59906064016020604051808303815f875af11580156102b0573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906102d4919061034e565b50505050565b80356001600160a01b03811681146102f0575f80fd5b919050565b5f60208284031215610305575f80fd5b61030e826102da565b9392505050565b5f805f60608486031215610327575f80fd5b610330846102da565b925061033e602085016102da565b9150604084013590509250925092565b5f6020828403121561035e575f80fd5b5051919050565b5f60208284031215610375575f80fd5b8151801515811461030e575f80fdfea2646970667358221220b0e7862174e2ff3387b0618b99934fd4cef8d9080a65c52745e11753d2685a4f64736f6c634300081a0033" + + +### Setup contracts ############################################################ + +## Admin approves pool to spend tokens for initial liquidity + +[[setup]] +kind = "admin_approve_pool_tokenA" +to = "{TokenA}" +signature = "approve(address spender, uint256 amount) returns (bool)" +args = [ + "{SandwichPool}", + "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", +] + +[[setup]] +kind = "admin_approve_pool_tokenB" +to = "{TokenB}" +signature = "approve(address spender, uint256 amount) returns (bool)" +args = [ + "{SandwichPool}", + "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", +] + +## Add initial liquidity (large amounts for deep pool) + +[[setup]] +kind = "admin_add_liquidity" +to = "{SandwichPool}" +signature = "addLiquidity(uint256 amountA, uint256 amountB)" +args = ["{liquidityAmount}", "{liquidityAmount}"] +gas_limit = 300000 + +## Fund SandwichBot with both tokens + +[[setup]] +kind = "fund_bot_tokenA" +to = "{TokenA}" +signature = "transfer(address to, uint256 amount) returns (bool)" +args = ["{SandwichBot}", "{botFunds}"] + +[[setup]] +kind = "fund_bot_tokenB" +to = "{TokenB}" +signature = "transfer(address to, uint256 amount) returns (bool)" +args = ["{SandwichBot}", "{botFunds}"] + +## Mint tokens to all victim spammer accounts and approve pool + +[[setup]] +kind = "mint_tokenA_to_victims" +to = "{TokenA}" +from_pool = "victims" +for_all_accounts = true +signature = "mint(address to, uint256 amount)" +args = ["{_sender}", "{spammerMintAmount}"] + +[[setup]] +kind = "victims_approve_pool_tokenA" +to = "{TokenA}" +from_pool = "victims" +for_all_accounts = true +signature = "approve(address spender, uint256 amount) returns (bool)" +args = [ + "{SandwichPool}", + "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", +] + +[[setup]] +kind = "mint_tokenB_to_victims" +to = "{TokenB}" +from_pool = "victims" +for_all_accounts = true +signature = "mint(address to, uint256 amount)" +args = ["{_sender}", "{spammerMintAmount}"] + +[[setup]] +kind = "victims_approve_pool_tokenB" +to = "{TokenB}" +from_pool = "victims" +for_all_accounts = true +signature = "approve(address spender, uint256 amount) returns (bool)" +args = [ + "{SandwichPool}", + "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", +] + +## Mint tokens to searcher accounts and approve pool (for direct swaps if needed) + +[[setup]] +kind = "mint_tokenA_to_searchers" +to = "{TokenA}" +from_pool = "searchers" +for_all_accounts = true +signature = "mint(address to, uint256 amount)" +args = ["{_sender}", "{spammerMintAmount}"] + +[[setup]] +kind = "mint_tokenB_to_searchers" +to = "{TokenB}" +from_pool = "searchers" +for_all_accounts = true +signature = "mint(address to, uint256 amount)" +args = ["{_sender}", "{spammerMintAmount}"] + + +### Spam patterns ############################################################## + +# Pattern 1: Normal victim swaps (standalone, not in a bundle) +# These represent regular user swaps that MEV bots would target +[[spam]] +[spam.tx] +kind = "victim_swap" +to = "{SandwichPool}" +from_pool = "victims" +signature = "swap(address tokenIn, uint256 amountIn, uint256 minAmountOut) returns (uint256)" +args = ["{TokenA}", "1000000000000000000", "0"] +fuzz = [{ param = "amountIn", min = "100000000000000000", max = "5000000000000000000" }] + +# Pattern 2: MEV Sandwich bundle (frontrun + victim + backrun) +# Atomic bundle ensures ordering: buy before victim, sell after victim +[[spam]] + +[[spam.bundle.tx]] +kind = "frontrun" +to = "{SandwichBot}" +from_pool = "searchers" +signature = "frontrun(address pool, address tokenIn, uint256 amountIn)" +args = ["{SandwichPool}", "{TokenA}", "2000000000000000000"] +gas_limit = 200000 +fuzz = [{ param = "amountIn", min = "500000000000000000", max = "5000000000000000000" }] + +[[spam.bundle.tx]] +kind = "victim_in_bundle" +to = "{SandwichPool}" +from_pool = "victims" +signature = "swap(address tokenIn, uint256 amountIn, uint256 minAmountOut) returns (uint256)" +args = ["{TokenA}", "1000000000000000000", "0"] +gas_limit = 200000 + +[[spam.bundle.tx]] +kind = "backrun" +to = "{SandwichBot}" +from_pool = "searchers" +signature = "backrun(address pool, address tokenIn, uint256 amountIn)" +args = ["{SandwichPool}", "{TokenB}", "2000000000000000000"] +gas_limit = 200000 +fuzz = [{ param = "amountIn", min = "500000000000000000", max = "5000000000000000000" }] diff --git a/scenarios/multicall3.toml b/scenarios/multicall3.toml new file mode 100644 index 00000000..0b2af3f9 --- /dev/null +++ b/scenarios/multicall3.toml @@ -0,0 +1,113 @@ +# ============================================================ +# Multicall3 Batched Transactions Stress Test +# ============================================================ +# Source: /tmp/multicall.sol (Solidity 0.8.26, optimized with 200 runs) +# Tests N heterogeneous calls in a single transaction via Multicall3. +# Exercises memory expansion, loop overhead, and mixed call patterns. +# +# Contracts: +# - Multicall3: aggregate3 / aggregate3Value for batching arbitrary calls +# - Counter: simple increment target for batched calls +# - SimpleToken: minimal ERC20 for mixed batches +# - MulticallHelper: constructs Call3[] arrays and invokes aggregate3 +# +# Spam patterns: +# 1. batchIncrement: 5-50 increment() calls batched via aggregate3 +# 2. batchIncrementBy: 5-20 incrementBy(n) calls, n fuzzed 1-100 +# 3. batchMixed: mix of increment + ERC20 transfer calls in one batch + +[env] +initialSupply = "1000000000000000000000000000" + +### Deploy contracts ########################################################### + +[[create]] +name = "Multicall3" +bytecode = "0x6080604052348015600e575f80fd5b506106358061001c5f395ff3fe60806040526004361061002b575f3560e01c8063174dea711461003657806382ad56cb1461005f575f80fd5b3661003257005b5f80fd5b61004961004436600461042d565b610072565b604051610056919061046c565b60405180910390f35b61004961006d36600461042d565b610235565b6060818067ffffffffffffffff81111561008e5761008e610507565b6040519080825280602002602001820160405280156100d357816020015b604080518082019091525f8152606060208201528152602001906001900390816100ac5790505b5091505f5b8181101561022d57368585838181106100f3576100f361051b565b9050602002810190610105919061052f565b90505f80610116602084018461054d565b6001600160a01b03166040840135610131606086018661057a565b60405161013f9291906105bd565b5f6040518083038185875af1925050503d805f8114610179576040519150601f19603f3d011682016040523d82523d5f602084013e61017e565b606091505b50909250905061019460408401602085016105cc565b15801561019f575081155b156101eb5760405162461bcd60e51b8152602060048201526017602482015276135d5b1d1a58d85b1b0cce8818d85b1b0819985a5b1959604a1b60448201526064015b60405180910390fd5b60405180604001604052808315158152602001828152508685815181106102145761021461051b565b60200260200101819052508360010193505050506100d8565b505092915050565b6060818067ffffffffffffffff81111561025157610251610507565b60405190808252806020026020018201604052801561029657816020015b604080518082019091525f81526060602082015281526020019060019003908161026f5790505b5091505f5b8181101561022d57368585838181106102b6576102b661051b565b90506020028101906102c891906105eb565b90505f806102d9602084018461054d565b6001600160a01b03166102ef604085018561057a565b6040516102fd9291906105bd565b5f604051808303815f865af19150503d805f8114610336576040519150601f19603f3d011682016040523d82523d5f602084013e61033b565b606091505b50909250905061035160408401602085016105cc565b15801561035c575081155b156103a35760405162461bcd60e51b8152602060048201526017602482015276135d5b1d1a58d85b1b0cce8818d85b1b0819985a5b1959604a1b60448201526064016101e2565b60405180604001604052808315158152602001828152508685815181106103cc576103cc61051b565b602002602001018190525083600101935050505061029b565b5f8083601f8401126103f5575f80fd5b50813567ffffffffffffffff81111561040c575f80fd5b6020830191508360208260051b8501011115610426575f80fd5b9250929050565b5f806020838503121561043e575f80fd5b823567ffffffffffffffff811115610454575f80fd5b610460858286016103e5565b90969095509350505050565b5f602082016020835280845180835260408501915060408160051b8601019250602086015f5b828110156104fb57603f198786030184528151805115158652602081015190506040602087015280518060408801528060208301606089015e5f606082890101526060601f19601f83011688010196505050602082019150602084019350600181019050610492565b50929695505050505050565b634e487b7160e01b5f52604160045260245ffd5b634e487b7160e01b5f52603260045260245ffd5b5f8235607e19833603018112610543575f80fd5b9190910192915050565b5f6020828403121561055d575f80fd5b81356001600160a01b0381168114610573575f80fd5b9392505050565b5f808335601e1984360301811261058f575f80fd5b83018035915067ffffffffffffffff8211156105a9575f80fd5b602001915036819003821315610426575f80fd5b818382375f9101908152919050565b5f602082840312156105dc575f80fd5b81358015158114610573575f80fd5b5f8235605e19833603018112610543575f80fdfea264697066735822122042fff7be075dcb8b55ee19a92a4d782761bd9d65e1cc631db591c9f705c0141a64736f6c634300081a0033" + +[[create]] +name = "Counter" +bytecode = "0x6080604052348015600e575f80fd5b506101af8061001c5f395ff3fe608060405234801561000f575f80fd5b506004361061004a575f3560e01c806303df179c1461004e5780630568e65e146100635780634f0cd27b14610094578063d09de08a146100bc575b5f80fd5b61006161005c366004610110565b6100c4565b005b610082610071366004610127565b5f6020819052908152604090205481565b60405190815260200160405180910390f35b6100826100a2366004610127565b6001600160a01b03165f9081526020819052604090205490565b6100616100ea565b335f90815260208190526040812080548392906100e2908490610154565b909155505050565b335f908152602081905260408120805460019290610109908490610154565b9091555050565b5f60208284031215610120575f80fd5b5035919050565b5f60208284031215610137575f80fd5b81356001600160a01b038116811461014d575f80fd5b9392505050565b8082018082111561017357634e487b7160e01b5f52601160045260245ffd5b9291505056fea2646970667358221220780095241697c7e8eea5ae92690c913f2e887ac649275478f4672feabb0fd04c64736f6c634300081a0033" + +[[create]] +name = "SimpleToken" +signature = "(uint256)" +args = ["{initialSupply}"] +bytecode = "0x60c0604052600b60809081526a29b4b6b83632aa37b5b2b760a91b60a0525f906100299082610162565b5060408051808201909152600381526253544b60e81b60208201526001906100519082610162565b5034801561005d575f80fd5b506040516108ab3803806108ab83398101604081905261007c9161021c565b6002819055335f818152600360209081526040808320859055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a350610233565b634e487b7160e01b5f52604160045260245ffd5b600181811c908216806100f257607f821691505b60208210810361011057634e487b7160e01b5f52602260045260245ffd5b50919050565b601f82111561015d57805f5260205f20601f840160051c8101602085101561013b5750805b601f840160051c820191505b8181101561015a575f8155600101610147565b50505b505050565b81516001600160401b0381111561017b5761017b6100ca565b61018f8161018984546100de565b84610116565b6020601f8211600181146101c1575f83156101aa5750848201515b5f19600385901b1c1916600184901b17845561015a565b5f84815260208120601f198516915b828110156101f057878501518255602094850194600190920191016101d0565b508482101561020d57868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b5f6020828403121561022c575f80fd5b5051919050565b61066b806102405f395ff3fe608060405234801561000f575f80fd5b506004361061009b575f3560e01c806340c10f191161006357806340c10f191461012457806370a082311461013957806395d89b4114610158578063a9059cbb14610160578063dd62ed3e14610173575f80fd5b806306fdde031461009f578063095ea7b3146100bd57806318160ddd146100e057806323b872dd146100f7578063313ce5671461010a575b5f80fd5b6100a761019d565b6040516100b491906104c0565b60405180910390f35b6100d06100cb366004610510565b610228565b60405190151581526020016100b4565b6100e960025481565b6040519081526020016100b4565b6100d0610105366004610538565b610294565b610112601281565b60405160ff90911681526020016100b4565b610137610132366004610510565b61039f565b005b6100e9610147366004610572565b60036020525f908152604090205481565b6100a7610425565b6100d061016e366004610510565b610432565b6100e9610181366004610592565b600460209081525f928352604080842090915290825290205481565b5f80546101a9906105c3565b80601f01602080910402602001604051908101604052809291908181526020018280546101d5906105c3565b80156102205780601f106101f757610100808354040283529160200191610220565b820191905f5260205f20905b81548152906001019060200180831161020357829003601f168201915b505050505081565b335f8181526004602090815260408083206001600160a01b038716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925906102829086815260200190565b60405180910390a35060015b92915050565b6001600160a01b0383165f9081526004602090815260408083203384529091528120545f1981146102ed576102c9838261060f565b6001600160a01b0386165f9081526004602090815260408083203384529091529020555b6001600160a01b0385165f908152600360205260408120805485929061031490849061060f565b90915550506001600160a01b0384165f9081526003602052604081208054859290610340908490610622565b92505081905550836001600160a01b0316856001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8560405161038c91815260200190565b60405180910390a3506001949350505050565b8060025f8282546103b09190610622565b90915550506001600160a01b0382165f90815260036020526040812080548392906103dc908490610622565b90915550506040518181526001600160a01b038316905f907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b600180546101a9906105c3565b335f9081526003602052604081208054839190839061045290849061060f565b90915550506001600160a01b0383165f908152600360205260408120805484929061047e908490610622565b90915550506040518281526001600160a01b0384169033907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602001610282565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f83011684010191505092915050565b80356001600160a01b038116811461050b575f80fd5b919050565b5f8060408385031215610521575f80fd5b61052a836104f5565b946020939093013593505050565b5f805f6060848603121561054a575f80fd5b610553846104f5565b9250610561602085016104f5565b929592945050506040919091013590565b5f60208284031215610582575f80fd5b61058b826104f5565b9392505050565b5f80604083850312156105a3575f80fd5b6105ac836104f5565b91506105ba602084016104f5565b90509250929050565b600181811c908216806105d757607f821691505b6020821081036105f557634e487b7160e01b5f52602260045260245ffd5b50919050565b634e487b7160e01b5f52601160045260245ffd5b8181038181111561028e5761028e6105fb565b8082018082111561028e5761028e6105fb56fea26469706673582212206128c253e13e1fca9603f5b80e887aa56e652a81d14b6607ed74d6683d48be1064736f6c634300081a0033" + +[[create]] +name = "MulticallHelper" +bytecode = "0x6080604052348015600e575f80fd5b506109558061001c5f395ff3fe608060405234801561000f575f80fd5b506004361061003f575f3560e01c8063625a9a40146100435780636be0abf814610058578063ada415041461006b575b5f80fd5b61005661005136600461057a565b61007e565b005b6100566100663660046105b9565b6101f3565b6100566100793660046105f3565b610352565b5f8267ffffffffffffffff8111156100985761009861064e565b6040519080825280602002602001820160405280156100e457816020015b60408051606080820183525f8083526020830152918101919091528152602001906001900390816100b65790505b5090505f826040516024016100fb91815260200190565b60408051601f198184030181529190526020810180516001600160e01b031662f7c5e760e21b17905290505f5b8481101561017b576040518060600160405280876001600160a01b031681526020015f151581526020018381525083828151811061016857610168610662565b6020908102919091010152600101610128565b506040516382ad56cb60e01b81526001600160a01b038716906382ad56cb906101a8908590600401610676565b5f604051808303815f875af11580156101c3573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526101ea919081019061077d565b50505050505050565b5f8167ffffffffffffffff81111561020d5761020d61064e565b60405190808252806020026020018201604052801561025957816020015b60408051606080820183525f80835260208301529181019190915281526020019060019003908161022b5790505b506040805160048152602481019091526020810180516001600160e01b031663684ef04560e11b1790529091505f5b838110156102db576040518060600160405280866001600160a01b031681526020015f15158152602001838152508382815181106102c8576102c8610662565b6020908102919091010152600101610288565b506040516382ad56cb60e01b81526001600160a01b038616906382ad56cb90610308908590600401610676565b5f604051808303815f875af1158015610323573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f1916820160405261034a919081019061077d565b505050505050565b5f61035d83856108fa565b90505f8167ffffffffffffffff8111156103795761037961064e565b6040519080825280602002602001820160405280156103c557816020015b60408051606080820183525f8083526020830152918101919091528152602001906001900390816103975790505b506040805160048152602481019091526020810180516001600160e01b031663684ef04560e11b1790529091505f5b868110156104475760405180606001604052808a6001600160a01b031681526020015f151581526020018381525083828151811061043457610434610662565b60209081029190910101526001016103f4565b50604051306024820152604481018590525f9060640160408051601f198184030181529190526020810180516001600160e01b031663a9059cbb60e01b17905290505f5b868110156104e357604080516060810182526001600160a01b038b1681525f6020820152908101839052846104c0838b6108fa565b815181106104d0576104d0610662565b602090810291909101015260010161048b565b506040516382ad56cb60e01b81526001600160a01b038b16906382ad56cb90610510908690600401610676565b5f604051808303815f875af115801561052b573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052610552919081019061077d565b5050505050505050505050565b80356001600160a01b0381168114610575575f80fd5b919050565b5f805f806080858703121561058d575f80fd5b6105968561055f565b93506105a46020860161055f565b93969395505050506040820135916060013590565b5f805f606084860312156105cb575f80fd5b6105d48461055f565b92506105e26020850161055f565b929592945050506040919091013590565b5f805f805f8060c08789031215610608575f80fd5b6106118761055f565b955061061f6020880161055f565b945061062d6040880161055f565b959894975094956060810135955060808101359460a0909101359350915050565b634e487b7160e01b5f52604160045260245ffd5b634e487b7160e01b5f52603260045260245ffd5b5f602082016020835280845180835260408501915060408160051b8601019250602086015f5b8281101561071757603f19878603018452815160018060a01b038151168652602081015115156020870152604081015190506060604087015280518060608801528060208301608089015e5f608082890101526080601f19601f8301168801019650505060208201915060208401935060018101905061069c565b50929695505050505050565b6040805190810167ffffffffffffffff811182821017156107465761074661064e565b60405290565b604051601f8201601f1916810167ffffffffffffffff811182821017156107755761077561064e565b604052919050565b5f6020828403121561078d575f80fd5b815167ffffffffffffffff8111156107a3575f80fd5b8201601f810184136107b3575f80fd5b805167ffffffffffffffff8111156107cd576107cd61064e565b8060051b6107dd6020820161074c565b918252602081840181019290810190878411156107f8575f80fd5b6020850192505b838310156108ef57825167ffffffffffffffff81111561081d575f80fd5b85016040818a03601f19011215610832575f80fd5b61083a610723565b6020820151801515811461084c575f80fd5b8152604082015167ffffffffffffffff811115610867575f80fd5b60208184010192505089601f83011261087e575f80fd5b815167ffffffffffffffff8111156108985761089861064e565b6108ab601f8201601f191660200161074c565b8181528b60208386010111156108bf575f80fd5b8160208501602083015e5f60208383010152806020840152505080845250506020820191506020830192506107ff565b979650505050505050565b8082018082111561091957634e487b7160e01b5f52601160045260245ffd5b9291505056fea264697066735822122015e206c44d7c385d7e2f3be320d5920331e164928021a8d79cc4ac37bd91ab2264736f6c634300081a0033" + + +### Setup contracts ############################################################# + +# Mint tokens to the MulticallHelper contract so it can do ERC20 transfers in batchMixed +[[setup]] +kind = "mint_to_helper" +to = "{SimpleToken}" +signature = "mint(address to, uint256 amount)" +args = ["{MulticallHelper}", "1000000000000000000000000000"] + +# Mint tokens to each spammer account (for approvals) +[[setup]] +kind = "mint_to_spammers" +to = "{SimpleToken}" +from_pool = "spammer" +for_all_accounts = true +signature = "mint(address to, uint256 amount)" +args = ["{_sender}", "1000000000000000000000000"] + +# Each spammer approves the MulticallHelper to spend their tokens +[[setup]] +kind = "approve_helper" +to = "{SimpleToken}" +from_pool = "spammer" +for_all_accounts = true +signature = "approve(address spender, uint256 amount) returns (bool)" +args = ["{MulticallHelper}", "115792089237316195423570985008687907853269984665640564039457584007913129639935"] + + +### Spam patterns ############################################################## + +# Pattern 1: batchIncrement - fuzz `times` from 5 to 50 +# Each tx batches N increment() calls through Multicall3 +[[spam]] +[spam.tx] +kind = "batch_increment" +to = "{MulticallHelper}" +from_pool = "batch_small" +signature = "function batchIncrement(address multicall, address counter, uint256 times)" +args = ["{Multicall3}", "{Counter}", "25"] +fuzz = [{ param = "times", min = "5", max = "50" }] +gas_limit = 5000000 + +# Pattern 2: batchIncrementBy - fuzz `times` 5-20 and `n` 1-100 +# Each tx batches N incrementBy(n) calls through Multicall3 +[[spam]] +[spam.tx] +kind = "batch_increment_by" +to = "{MulticallHelper}" +from_pool = "batch_compute" +signature = "function batchIncrementBy(address multicall, address counter, uint256 times, uint256 n)" +args = ["{Multicall3}", "{Counter}", "10", "50"] +fuzz = [ + { param = "times", min = "5", max = "20" }, + { param = "n", min = "1", max = "100" } +] +gas_limit = 3000000 + +# Pattern 3: batchMixed - fuzz numIncrements 3-10 and numTransfers 3-10 +# Mixes Counter.increment() calls with ERC20 self-transfers in one batch +[[spam]] +[spam.tx] +kind = "batch_mixed" +to = "{MulticallHelper}" +from_pool = "batch_mixed" +signature = "function batchMixed(address multicall, address counter, address token, uint256 numIncrements, uint256 numTransfers, uint256 transferAmount)" +args = ["{Multicall3}", "{Counter}", "{SimpleToken}", "5", "5", "1000000000000000000"] +fuzz = [ + { param = "numIncrements", min = "3", max = "10" }, + { param = "numTransfers", min = "3", max = "10" } +] +gas_limit = 5000000 diff --git a/scenarios/multisig.toml b/scenarios/multisig.toml new file mode 100644 index 00000000..abbd876a --- /dev/null +++ b/scenarios/multisig.toml @@ -0,0 +1,124 @@ +# ============================================================ +# SimpleMultiSig - Multi-Signature Wallet Stress Test +# ============================================================ +# Source: /tmp/multisig.sol (Solidity 0.8.26, optimized with 200 runs) +# Gas profile: ~90k submitTransaction, ~65k confirmTransaction, +# ~45k executeTransaction (varies with external call), +# ~35k revokeConfirmation +# Patterns: dynamic array growth, nested mappings, external calls, +# event emissions, require checks +# ============================================================ + +[env] +max_tx_id = "99" + +## Deploy the multisig contract with requiredConfirmations = 2 +[[create]] +name = "MultiSig" +bytecode = "0x6080604052348015600e575f80fd5b50604051610d17380380610d17833981016040819052602b916072565b5f8111606c5760405162461bcd60e51b815260206004820152600c60248201526b07265717569726564203e20360a41b604482015260640160405180910390fd5b5f556088565b5f602082840312156081575f80fd5b5051919050565b610c82806100955f395ff3fe60806040526004361061007c575f3560e01c80639ace38c21161004c5780639ace38c214610128578063c01a8c8414610158578063c642747414610177578063ee22610b14610196575f80fd5b806320ea8d86146100875780632e7700f0146100a85780633411c81c146100cb57806382e717f714610114575f80fd5b3661008357005b5f80fd5b348015610092575f80fd5b506100a66100a136600461081d565b6101b5565b005b3480156100b3575f80fd5b506001545b6040519081526020015b60405180910390f35b3480156100d6575f80fd5b506101046100e536600461084f565b600260209081525f928352604080842090915290825290205460ff1681565b60405190151581526020016100c2565b34801561011f575f80fd5b506100b85f5481565b348015610133575f80fd5b5061014761014236600461081d565b610304565b6040516100c29594939291906108a7565b348015610163575f80fd5b506100a661017236600461081d565b6103d9565b348015610182575f80fd5b506100b86101913660046108f5565b610528565b3480156101a1575f80fd5b506100a66101b036600461081d565b61066f565b60015481106101df5760405162461bcd60e51b81526004016101d6906109c1565b60405180910390fd5b600181815481106101f2576101f26109ec565b5f91825260209091206003600590920201015460ff16156102255760405162461bcd60e51b81526004016101d690610a00565b5f81815260026020908152604080832033845290915290205460ff1661027d5760405162461bcd60e51b815260206004820152600d60248201526c1b9bdd0818dbdb999a5c9b5959609a1b60448201526064016101d6565b5f8181526002602090815260408083203384529091529020805460ff19169055600180548190839081106102b3576102b36109ec565b905f5260205f2090600502016004015f8282546102d09190610a41565b9091555050604051819033907ff0dca620e2e81f7841d07bcc105e1704fb01475b278a9d4c236e1c62945edd55905f90a350565b60018181548110610313575f80fd5b5f9182526020909120600590910201805460018201546002830180546001600160a01b03909316945090929161034890610a5a565b80601f016020809104026020016040519081016040528092919081815260200182805461037490610a5a565b80156103bf5780601f10610396576101008083540402835291602001916103bf565b820191905f5260205f20905b8154815290600101906020018083116103a257829003601f168201915b505050506003830154600490930154919260ff1691905085565b60015481106103fa5760405162461bcd60e51b81526004016101d6906109c1565b6001818154811061040d5761040d6109ec565b5f91825260209091206003600590920201015460ff16156104405760405162461bcd60e51b81526004016101d690610a00565b5f81815260026020908152604080832033845290915290205460ff161561049d5760405162461bcd60e51b8152602060048201526011602482015270185b1c9958591e4818dbdb999a5c9b5959607a1b60448201526064016101d6565b5f8181526002602090815260408083203384529091529020805460ff1916600190811790915580548190839081106104d7576104d76109ec565b905f5260205f2090600502016004015f8282546104f49190610a92565b9091555050604051819033907f5cbe105e36805f7820e291f799d5794ff948af2a5f664e580382defb63390041905f90a350565b600180546040805160a0810182526001600160a01b038781168252602082018781529282018681525f606084018190526080840181905285870187559590955281517fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf66005860290810180546001600160a01b0319169290931691909117825592517fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf784015593519293909290917fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf801906106039082610af1565b50606082015160038201805460ff1916911515919091179055608090910151600490910155604051819033907fd5a05bf70715ad82a09a756320284a1b54c9ff74cd0f8cce6219e79b563fe59d9061066090889088908890610bac565b60405180910390a39392505050565b60015481106106905760405162461bcd60e51b81526004016101d6906109c1565b5f600182815481106106a4576106a46109ec565b5f9182526020909120600590910201600381015490915060ff16156106db5760405162461bcd60e51b81526004016101d690610a00565b5f54816004015410156107305760405162461bcd60e51b815260206004820152601860248201527f6e6f7420656e6f75676820636f6e6669726d6174696f6e73000000000000000060448201526064016101d6565b60038101805460ff191660019081179091558154908201546040515f926001600160a01b03169190610766906002860190610bdb565b5f6040518083038185875af1925050503d805f81146107a0576040519150601f19603f3d011682016040523d82523d5f602084013e6107a5565b606091505b50509050806107ec5760405162461bcd60e51b81526020600482015260136024820152721d1e08195e1958dd5d1a5bdb8819985a5b1959606a1b60448201526064016101d6565b604051839033907f5445f318f4f5fcfb66592e68e0cc5822aa15664039bd5f0ffde24c5a8142b1ac905f90a3505050565b5f6020828403121561082d575f80fd5b5035919050565b80356001600160a01b038116811461084a575f80fd5b919050565b5f8060408385031215610860575f80fd5b8235915061087060208401610834565b90509250929050565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b60018060a01b038616815284602082015260a060408201525f6108cd60a0830186610879565b931515606083015250608001529392505050565b634e487b7160e01b5f52604160045260245ffd5b5f805f60608486031215610907575f80fd5b61091084610834565b925060208401359150604084013567ffffffffffffffff811115610932575f80fd5b8401601f81018613610942575f80fd5b803567ffffffffffffffff81111561095c5761095c6108e1565b604051601f8201601f19908116603f0116810167ffffffffffffffff8111828210171561098b5761098b6108e1565b6040528181528282016020018810156109a2575f80fd5b816020840160208301375f602083830101528093505050509250925092565b6020808252601190820152701d1e08191bd95cc81b9bdd08195e1a5cdd607a1b604082015260600190565b634e487b7160e01b5f52603260045260245ffd5b6020808252601390820152721d1e08185b1c9958591e48195e1958dd5d1959606a1b604082015260600190565b634e487b7160e01b5f52601160045260245ffd5b81810381811115610a5457610a54610a2d565b92915050565b600181811c90821680610a6e57607f821691505b602082108103610a8c57634e487b7160e01b5f52602260045260245ffd5b50919050565b80820180821115610a5457610a54610a2d565b601f821115610aec57805f5260205f20601f840160051c81016020851015610aca5750805b601f840160051c820191505b81811015610ae9575f8155600101610ad6565b50505b505050565b815167ffffffffffffffff811115610b0b57610b0b6108e1565b610b1f81610b198454610a5a565b84610aa5565b6020601f821160018114610b51575f8315610b3a5750848201515b5f19600385901b1c1916600184901b178455610ae9565b5f84815260208120601f198516915b82811015610b805787850151825560209485019460019092019101610b60565b5084821015610b9d57868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b60018060a01b0384168152826020820152606060408201525f610bd26060830184610879565b95945050505050565b5f808354610be881610a5a565b600182168015610bff5760018114610c1457610c41565b60ff1983168652811515820286019350610c41565b865f5260205f205f5b83811015610c3957815488820152600190910190602001610c1d565b505081860193505b50919594505050505056fea26469706673582212203231754d4c4ff95c8467d55bf17342a5705220d786c76f136abbd657b0ec592364736f6c634300081a0033" +signature = "constructor(uint256)" +args = ["2"] + + +## Setup: fund the multisig contract with ETH (plain transfer, no calldata) +[[setup]] +kind = "fund_multisig" +to = "{MultiSig}" +value = "10 eth" + +## Setup: submit 10 initial transactions (IDs 0-9) from admin +[[setup]] +kind = "submit_tx_0" +to = "{MultiSig}" +signature = "function submitTransaction(address to, uint256 value, bytes memory data) external returns (uint256)" +args = ["{_sender}", "1000000000000000", "0x"] + +[[setup]] +kind = "submit_tx_1" +to = "{MultiSig}" +signature = "function submitTransaction(address to, uint256 value, bytes memory data) external returns (uint256)" +args = ["{_sender}", "2000000000000000", "0x"] + +[[setup]] +kind = "submit_tx_2" +to = "{MultiSig}" +signature = "function submitTransaction(address to, uint256 value, bytes memory data) external returns (uint256)" +args = ["{_sender}", "3000000000000000", "0x"] + +[[setup]] +kind = "submit_tx_3" +to = "{MultiSig}" +signature = "function submitTransaction(address to, uint256 value, bytes memory data) external returns (uint256)" +args = ["{_sender}", "4000000000000000", "0x"] + +[[setup]] +kind = "submit_tx_4" +to = "{MultiSig}" +signature = "function submitTransaction(address to, uint256 value, bytes memory data) external returns (uint256)" +args = ["{_sender}", "5000000000000000", "0x"] + +[[setup]] +kind = "submit_tx_5" +to = "{MultiSig}" +signature = "function submitTransaction(address to, uint256 value, bytes memory data) external returns (uint256)" +args = ["{_sender}", "1000000000000000", "0x"] + +[[setup]] +kind = "submit_tx_6" +to = "{MultiSig}" +signature = "function submitTransaction(address to, uint256 value, bytes memory data) external returns (uint256)" +args = ["{_sender}", "2000000000000000", "0x"] + +[[setup]] +kind = "submit_tx_7" +to = "{MultiSig}" +signature = "function submitTransaction(address to, uint256 value, bytes memory data) external returns (uint256)" +args = ["{_sender}", "3000000000000000", "0x"] + +[[setup]] +kind = "submit_tx_8" +to = "{MultiSig}" +signature = "function submitTransaction(address to, uint256 value, bytes memory data) external returns (uint256)" +args = ["{_sender}", "4000000000000000", "0x"] + +[[setup]] +kind = "submit_tx_9" +to = "{MultiSig}" +signature = "function submitTransaction(address to, uint256 value, bytes memory data) external returns (uint256)" +args = ["{_sender}", "5000000000000000", "0x"] + + +## Spam 1: submit new transactions to the multisig +[[spam]] +[spam.tx] +kind = "submit_transaction" +to = "{MultiSig}" +from_pool = "submitters" +signature = "function submitTransaction(address to, uint256 value, bytes memory data) external returns (uint256)" +args = ["{_sender}", "1000000000000", "0x"] + +## Spam 2: confirm existing transactions (may revert if already confirmed or txId doesn't exist) +[[spam]] +[spam.tx] +kind = "confirm_transaction" +to = "{MultiSig}" +from_pool = "confirmers" +signature = "function confirmTransaction(uint256 txId) external" +args = ["0"] +gas_limit = 120000 +fuzz = [ + { param = "txId", min = "0", max = "{max_tx_id}" }, +] + +## Spam 3: execute transactions (may revert if not enough confirmations) +[[spam]] +[spam.tx] +kind = "execute_transaction" +to = "{MultiSig}" +from_pool = "executors" +signature = "function executeTransaction(uint256 txId) external" +args = ["0"] +gas_limit = 150000 +fuzz = [ + { param = "txId", min = "0", max = "{max_tx_id}" }, +] diff --git a/scenarios/nameRegistry.toml b/scenarios/nameRegistry.toml new file mode 100644 index 00000000..c8fa3479 --- /dev/null +++ b/scenarios/nameRegistry.toml @@ -0,0 +1,73 @@ +# Name Registration Service (ENS-like) +# Tests: storage-heavy registration, renewals, record updates with keccak256 hashing + +[env] +# Pre-defined names for setup (as bytes32 values) +name_alice = "0x616c696365000000000000000000000000000000000000000000000000000000" +name_bob = "0x626f620000000000000000000000000000000000000000000000000000000000" +name_carol = "0x6361726f6c000000000000000000000000000000000000000000000000000000" + + +# Deploy SimpleNameRegistry +[[create]] +name = "SimpleNameRegistry" +# source: /tmp/nameregistry.sol +# compiled with: solc --bin --optimize --optimize-runs 200 +bytecode = "0x6080604052348015600e575f80fd5b506107628061001c5f395ff3fe608060405260043610610084575f3560e01c806379ce9fac1161005757806379ce9fac146101705780638e32762d14610191578063d9b76ed4146101a4578063e1fa8e84146101c3578063e98523aa146101d6575f80fd5b806320c38e2b14610088578063418cc2ae146100fa5780634c1342df146101225780635c23bdf514610139575b5f80fd5b348015610093575f80fd5b506100cf6100a236600461066e565b5f602081905290815260409020805460018201546002909201546001600160a01b03918216929091169083565b604080516001600160a01b039485168152939092166020840152908201526060015b60405180910390f35b348015610105575f80fd5b5061011466038d7ea4c6800081565b6040519081526020016100f1565b34801561012d575f80fd5b506101146301e1338081565b348015610144575f80fd5b5061015861015336600461066e565b6101f0565b6040516001600160a01b0390911681526020016100f1565b34801561017b575f80fd5b5061018f61018a366004610685565b61024d565b005b61018f61019f36600461066e565b610350565b3480156101af575f80fd5b5061018f6101be366004610685565b61045d565b61018f6101d136600461066e565b610515565b3480156101e1575f80fd5b506101146601c6bf5263400081565b5f806101fb8361063d565b5f8181526020819052604090206002810154919250904211156102395760405162461bcd60e51b8152600401610230906106be565b60405180910390fd5b600101546001600160a01b03169392505050565b6001600160a01b0381166102955760405162461bcd60e51b815260206004820152600f60248201526e496e76616c6964206164647265737360881b6044820152606401610230565b5f61029f8361063d565b5f8181526020819052604090208054919250906001600160a01b031633146102d95760405162461bcd60e51b8152600401610230906106e4565b80600201544211156102fd5760405162461bcd60e51b8152600401610230906106be565b80546001600160a01b031981166001600160a01b038581169182178455604051921691829085907fee3ae35c0d0799fb196f821efc8d30111345552cd23192da6bab51e7f664b6ba905f90a45050505050565b6601c6bf5263400034101561039a5760405162461bcd60e51b815260206004820152601060248201526f496e73756666696369656e742066656560801b6044820152606401610230565b5f6103a48261063d565b5f8181526020819052604090208054919250906001600160a01b031633146103de5760405162461bcd60e51b8152600401610230906106e4565b80600201544211156104025760405162461bcd60e51b8152600401610230906106be565b6301e13380816002015f8282546104199190610707565b9091555050600281015460405190815282907f5a773044a6c2a5ab1c7812c9417486344a3aa701e02afef1026ba9e1bebeed949060200160405180910390a2505050565b5f6104678361063d565b5f8181526020819052604090208054919250906001600160a01b031633146104a15760405162461bcd60e51b8152600401610230906106e4565b80600201544211156104c55760405162461bcd60e51b8152600401610230906106be565b6001810180546001600160a01b0319166001600160a01b03851690811790915560405183907f0596aa396eab4e69aca55f612009f548a14767e50000a5446fbebc9dcc43820c905f90a350505050565b66038d7ea4c6800034101561055f5760405162461bcd60e51b815260206004820152601060248201526f496e73756666696369656e742066656560801b6044820152606401610230565b5f6105698261063d565b5f8181526020819052604090208054919250906001600160a01b031615806105945750806002015442115b6105cd5760405162461bcd60e51b815260206004820152600a6024820152692730b6b2903a30b5b2b760b11b6044820152606401610230565b8054336001600160a01b0319918216811783556001830180549092161790556105fa6301e1338042610707565b60028201819055604051908152339083907fb6090d914a9708da24e13a3c0752d4b6d484ba0c8a9a25ca6f3ced6a0d0feb009060200160405180910390a3505050565b5f8160405160200161065191815260200190565b604051602081830303815290604052805190602001209050919050565b5f6020828403121561067e575f80fd5b5035919050565b5f8060408385031215610696575f80fd5b8235915060208301356001600160a01b03811681146106b3575f80fd5b809150509250929050565b6020808252600c908201526b13985b5948195e1c1a5c995960a21b604082015260600190565b6020808252600990820152682737ba1037bbb732b960b91b604082015260600190565b8082018082111561072657634e487b7160e01b5f52601160045260245ffd5b9291505056fea2646970667358221220d7e4072f21f01fb9f0145abbf8caa14883c301b71e14c201d925a07c849bee7664736f6c634300081a0033" + + +# Setup: register a few names so we have state for renew/setRecord spam +[[setup]] +to = "{SimpleNameRegistry}" +kind = "register_alice" +signature = "register(bytes32 name)" +args = ["{name_alice}"] +value = "0.001 eth" + +[[setup]] +to = "{SimpleNameRegistry}" +kind = "register_bob" +signature = "register(bytes32 name)" +args = ["{name_bob}"] +value = "0.001 eth" + +[[setup]] +to = "{SimpleNameRegistry}" +kind = "register_carol" +signature = "register(bytes32 name)" +args = ["{name_carol}"] +value = "0.001 eth" + + +# Spam 1: Register new names with fuzzed bytes32 (collisions extremely rare) +[[spam]] +[spam.tx] +kind = "register_new_name" +to = "{SimpleNameRegistry}" +from_pool = "registrants" +signature = "function register(bytes32 name) payable" +args = ["{name_alice}"] +value = "0.001 eth" +gas_limit = 150000 +fuzz = [{ param = "name", min = "0", max = "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" }] + +# Spam 2: Renew an existing name (registered in setup) +[[spam]] +[spam.tx] +kind = "renew_name" +to = "{SimpleNameRegistry}" +from_pool = "admin" +signature = "function renew(bytes32 name) payable" +args = ["{name_alice}"] +value = "0.0005 eth" +gas_limit = 100000 + +# Spam 3: Set resolver record for a registered name +[[spam]] +[spam.tx] +kind = "set_record" +to = "{SimpleNameRegistry}" +from_pool = "admin" +signature = "function setRecord(bytes32 name, address addr)" +args = ["{name_bob}", "0x0000000000000000000000000000000000000001"] +gas_limit = 100000 diff --git a/scenarios/orderBook.toml b/scenarios/orderBook.toml new file mode 100644 index 00000000..2d152f9f --- /dev/null +++ b/scenarios/orderBook.toml @@ -0,0 +1,123 @@ +# Simple On-Chain Order Book +# +# Deploys two ERC20 tokens (BaseToken, QuoteToken) and a SimpleOrderBook contract. +# Spammers place buy/sell orders and attempt cancellations to exercise array storage +# operations, token transfers, and matching logic with multiple storage reads/writes. +# +# source: /tmp/orderbook.sol +# compiled with: solc --bin --optimize --optimize-runs 200 + +### template variables +[env] +initialSupply = "1000000000000000000000000000" + +### deploy BaseToken (OrderBookToken) with initialSupply +[[create]] +name = "BaseToken" +signature = "(uint256 initialSupply)" +args = ["{initialSupply}"] +bytecode = "0x60c0604052600e60809081526d27b93232b92137b7b5aa37b5b2b760911b60a0525f9061002c9082610172565b5060408051808201909152600381526213d09560ea1b60208201526001906100549082610172565b506002805460ff1916601217905534801561006d575f80fd5b506040516109be3803806109be83398101604081905261008c9161022c565b6003819055335f818152600460209081526040808320859055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a350610243565b634e487b7160e01b5f52604160045260245ffd5b600181811c9082168061010257607f821691505b60208210810361012057634e487b7160e01b5f52602260045260245ffd5b50919050565b601f82111561016d57805f5260205f20601f840160051c8101602085101561014b5750805b601f840160051c820191505b8181101561016a575f8155600101610157565b50505b505050565b81516001600160401b0381111561018b5761018b6100da565b61019f8161019984546100ee565b84610126565b6020601f8211600181146101d1575f83156101ba5750848201515b5f19600385901b1c1916600184901b17845561016a565b5f84815260208120601f198516915b8281101561020057878501518255602094850194600190920191016101e0565b508482101561021d57868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b5f6020828403121561023c575f80fd5b5051919050565b61076e806102505f395ff3fe608060405234801561000f575f80fd5b506004361061009b575f3560e01c806340c10f191161006357806340c10f191461012957806370a082311461013e57806395d89b411461015d578063a9059cbb14610165578063dd62ed3e14610178575f80fd5b806306fdde031461009f578063095ea7b3146100bd57806318160ddd146100e057806323b872dd146100f7578063313ce5671461010a575b5f80fd5b6100a76101a2565b6040516100b491906105c3565b60405180910390f35b6100d06100cb366004610613565b61022d565b60405190151581526020016100b4565b6100e960035481565b6040519081526020016100b4565b6100d061010536600461063b565b610299565b6002546101179060ff1681565b60405160ff90911681526020016100b4565b61013c610137366004610613565b61044f565b005b6100e961014c366004610675565b60046020525f908152604090205481565b6100a76104d5565b6100d0610173366004610613565b6104e2565b6100e9610186366004610695565b600560209081525f928352604080842090915290825290205481565b5f80546101ae906106c6565b80601f01602080910402602001604051908101604052809291908181526020018280546101da906106c6565b80156102255780601f106101fc57610100808354040283529160200191610225565b820191905f5260205f20905b81548152906001019060200180831161020857829003601f168201915b505050505081565b335f8181526005602090815260408083206001600160a01b038716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925906102879086815260200190565b60405180910390a35060015b92915050565b6001600160a01b0383165f908152600460205260408120548211156102fc5760405162461bcd60e51b8152602060048201526014602482015273696e73756666696369656e742062616c616e636560601b60448201526064015b60405180910390fd5b6001600160a01b0384165f9081526005602090815260408083203384529091529020548211156103675760405162461bcd60e51b8152602060048201526016602482015275696e73756666696369656e7420616c6c6f77616e636560501b60448201526064016102f3565b6001600160a01b0384165f90815260056020908152604080832033845290915281208054849290610399908490610712565b90915550506001600160a01b0384165f90815260046020526040812080548492906103c5908490610712565b90915550506001600160a01b0383165f90815260046020526040812080548492906103f1908490610725565b92505081905550826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161043d91815260200190565b60405180910390a35060019392505050565b8060035f8282546104609190610725565b90915550506001600160a01b0382165f908152600460205260408120805483929061048c908490610725565b90915550506040518181526001600160a01b038316905f907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b600180546101ae906106c6565b335f908152600460205260408120548211156105375760405162461bcd60e51b8152602060048201526014602482015273696e73756666696369656e742062616c616e636560601b60448201526064016102f3565b335f9081526004602052604081208054849290610555908490610712565b90915550506001600160a01b0383165f9081526004602052604081208054849290610581908490610725565b90915550506040518281526001600160a01b0384169033907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602001610287565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f83011684010191505092915050565b80356001600160a01b038116811461060e575f80fd5b919050565b5f8060408385031215610624575f80fd5b61062d836105f8565b946020939093013593505050565b5f805f6060848603121561064d575f80fd5b610656846105f8565b9250610664602085016105f8565b929592945050506040919091013590565b5f60208284031215610685575f80fd5b61068e826105f8565b9392505050565b5f80604083850312156106a6575f80fd5b6106af836105f8565b91506106bd602084016105f8565b90509250929050565b600181811c908216806106da57607f821691505b6020821081036106f857634e487b7160e01b5f52602260045260245ffd5b50919050565b634e487b7160e01b5f52601160045260245ffd5b81810381811115610293576102936106fe565b80820180821115610293576102936106fe56fea26469706673582212201f74df9af3cc29ac7b3debc54a3636d985f78b10ea49a162055f2e18f2d3c4ee64736f6c634300081a0033" + +### deploy QuoteToken (OrderBookToken) with initialSupply +[[create]] +name = "QuoteToken" +signature = "(uint256 initialSupply)" +args = ["{initialSupply}"] +bytecode = "0x60c0604052600e60809081526d27b93232b92137b7b5aa37b5b2b760911b60a0525f9061002c9082610172565b5060408051808201909152600381526213d09560ea1b60208201526001906100549082610172565b506002805460ff1916601217905534801561006d575f80fd5b506040516109be3803806109be83398101604081905261008c9161022c565b6003819055335f818152600460209081526040808320859055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a350610243565b634e487b7160e01b5f52604160045260245ffd5b600181811c9082168061010257607f821691505b60208210810361012057634e487b7160e01b5f52602260045260245ffd5b50919050565b601f82111561016d57805f5260205f20601f840160051c8101602085101561014b5750805b601f840160051c820191505b8181101561016a575f8155600101610157565b50505b505050565b81516001600160401b0381111561018b5761018b6100da565b61019f8161019984546100ee565b84610126565b6020601f8211600181146101d1575f83156101ba5750848201515b5f19600385901b1c1916600184901b17845561016a565b5f84815260208120601f198516915b8281101561020057878501518255602094850194600190920191016101e0565b508482101561021d57868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b5f6020828403121561023c575f80fd5b5051919050565b61076e806102505f395ff3fe608060405234801561000f575f80fd5b506004361061009b575f3560e01c806340c10f191161006357806340c10f191461012957806370a082311461013e57806395d89b411461015d578063a9059cbb14610165578063dd62ed3e14610178575f80fd5b806306fdde031461009f578063095ea7b3146100bd57806318160ddd146100e057806323b872dd146100f7578063313ce5671461010a575b5f80fd5b6100a76101a2565b6040516100b491906105c3565b60405180910390f35b6100d06100cb366004610613565b61022d565b60405190151581526020016100b4565b6100e960035481565b6040519081526020016100b4565b6100d061010536600461063b565b610299565b6002546101179060ff1681565b60405160ff90911681526020016100b4565b61013c610137366004610613565b61044f565b005b6100e961014c366004610675565b60046020525f908152604090205481565b6100a76104d5565b6100d0610173366004610613565b6104e2565b6100e9610186366004610695565b600560209081525f928352604080842090915290825290205481565b5f80546101ae906106c6565b80601f01602080910402602001604051908101604052809291908181526020018280546101da906106c6565b80156102255780601f106101fc57610100808354040283529160200191610225565b820191905f5260205f20905b81548152906001019060200180831161020857829003601f168201915b505050505081565b335f8181526005602090815260408083206001600160a01b038716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925906102879086815260200190565b60405180910390a35060015b92915050565b6001600160a01b0383165f908152600460205260408120548211156102fc5760405162461bcd60e51b8152602060048201526014602482015273696e73756666696369656e742062616c616e636560601b60448201526064015b60405180910390fd5b6001600160a01b0384165f9081526005602090815260408083203384529091529020548211156103675760405162461bcd60e51b8152602060048201526016602482015275696e73756666696369656e7420616c6c6f77616e636560501b60448201526064016102f3565b6001600160a01b0384165f90815260056020908152604080832033845290915281208054849290610399908490610712565b90915550506001600160a01b0384165f90815260046020526040812080548492906103c5908490610712565b90915550506001600160a01b0383165f90815260046020526040812080548492906103f1908490610725565b92505081905550826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161043d91815260200190565b60405180910390a35060019392505050565b8060035f8282546104609190610725565b90915550506001600160a01b0382165f908152600460205260408120805483929061048c908490610725565b90915550506040518181526001600160a01b038316905f907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b600180546101ae906106c6565b335f908152600460205260408120548211156105375760405162461bcd60e51b8152602060048201526014602482015273696e73756666696369656e742062616c616e636560601b60448201526064016102f3565b335f9081526004602052604081208054849290610555908490610712565b90915550506001600160a01b0383165f9081526004602052604081208054849290610581908490610725565b90915550506040518281526001600160a01b0384169033907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602001610287565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f83011684010191505092915050565b80356001600160a01b038116811461060e575f80fd5b919050565b5f8060408385031215610624575f80fd5b61062d836105f8565b946020939093013593505050565b5f805f6060848603121561064d575f80fd5b610656846105f8565b9250610664602085016105f8565b929592945050506040919091013590565b5f60208284031215610685575f80fd5b61068e826105f8565b9392505050565b5f80604083850312156106a6575f80fd5b6106af836105f8565b91506106bd602084016105f8565b90509250929050565b600181811c908216806106da57607f821691505b6020821081036106f857634e487b7160e01b5f52602260045260245ffd5b50919050565b634e487b7160e01b5f52601160045260245ffd5b81810381811115610293576102936106fe565b80820180821115610293576102936106fe56fea26469706673582212201f74df9af3cc29ac7b3debc54a3636d985f78b10ea49a162055f2e18f2d3c4ee64736f6c634300081a0033" + +### deploy SimpleOrderBook with both token addresses +[[create]] +name = "OrderBook" +signature = "(address baseToken_, address quoteToken_)" +args = ["{BaseToken}", "{QuoteToken}"] +bytecode = "0x6080604052348015600e575f80fd5b50604051610e12380380610e12833981016040819052602b916074565b5f80546001600160a01b039384166001600160a01b0319918216179091556001805492909316911617905560a0565b80516001600160a01b0381168114606f575f80fd5b919050565b5f80604083850312156084575f80fd5b608b83605a565b9150609760208401605a565b90509250929050565b610d65806100ad5f395ff3fe608060405234801561000f575f80fd5b506004361061009b575f3560e01c80638d0a5fbb116100635780638d0a5fbb14610140578063a4406bcd14610148578063a85c38ef1461015b578063c55dae63146101a4578063ee36d4ab146101b6575f80fd5b80631756353d1461009f578063217a4b70146100b45780632cc75967146100e4578063514fcac71461011a578063856652e91461012d575b5f80fd5b6100b26100ad366004610c08565b6101c9565b005b6001546100c7906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b61010c6100f2366004610c43565b6001600160a01b03165f9081526003602052604090205490565b6040519081526020016100db565b6100b2610128366004610c63565b610497565b61010c61013b366004610c7a565b610635565b60025461010c565b61010c610156366004610c08565b610660565b61016e610169366004610c63565b6107f8565b604080516001600160a01b039096168652602086019490945292840191909152151560608301521515608082015260a0016100db565b5f546100c7906001600160a01b031681565b61010c6101c4366004610c08565b610846565b600254821080156101db575060025481105b61021c5760405162461bcd60e51b815260206004820152600d60248201526c34b73b30b634b21037b93232b960991b60448201526064015b60405180910390fd5b5f6002838154811061023057610230610ca2565b905f5260205f20906004020190505f6002838154811061025257610252610ca2565b905f5260205f20906004020190508160030160019054906101000a900460ff16801561028757506003810154610100900460ff165b6102c05760405162461bcd60e51b815260206004820152600a6024820152696e6f742061637469766560b01b6044820152606401610213565b600382015460ff1680156102d95750600381015460ff16155b61031b5760405162461bcd60e51b81526020600482015260136024820152720dee4c8cae440e8f2e0ca40dad2e6dac2e8c6d606b1b6044820152606401610213565b8060010154826001015410156103645760405162461bcd60e51b815260206004820152600e60248201526d0e0e4d2c6ca40dad2e6dac2e8c6d60931b6044820152606401610213565b5f816002015483600201541061037e578160020154610384565b82600201545b90505f670de0b6b3a76400008285600101546103a09190610cca565b6103aa9190610ce7565b905081846002015f8282546103bf9190610d06565b9250508190555081836002015f8282546103d99190610d06565b909155505060028401545f036103f75760038401805461ff00191690555b82600201545f036104105760038301805461ff00191690555b5f54845461042b916001600160a01b03908116911684610a3d565b6001548354610447916001600160a01b03908116911683610a3d565b84867f82877c5945532f956e6718f78f5606b7b5d8efef5e22121a3d9bf4e708873edd866001015485604051610487929190918252602082015260400190565b60405180910390a3505050505050565b60025481106104d85760405162461bcd60e51b815260206004820152600d60248201526c34b73b30b634b21037b93232b960991b6044820152606401610213565b5f600282815481106104ec576104ec610ca2565b905f5260205f20906004020190508060030160019054906101000a900460ff166105455760405162461bcd60e51b815260206004820152600a6024820152696e6f742061637469766560b01b6044820152606401610213565b80546001600160a01b0316331461058a5760405162461bcd60e51b81526020600482015260096024820152683737ba1036b0b5b2b960b91b6044820152606401610213565b60038101805461ff0019811690915560ff16156105e9575f670de0b6b3a7640000826002015483600101546105bf9190610cca565b6105c99190610ce7565b6001549091506105e3906001600160a01b03163383610a3d565b50610605565b5f546002820154610605916001600160a01b0316903390610a3d565b604051339083907fc0362da6f2ff36b382b34aec0814f6b3cdf89f5ef282a1d1f114d0c0b036d596905f90a35050565b6003602052815f5260405f20818154811061064e575f80fd5b905f5260205f20015f91509150505481565b5f80546106789061067e906001600160a01b0316333085610b1c565b50600280546040805160a0810182523380825260208083018881528385018881525f6060808701828152600160808901818152818c018d559b8452975160048b027f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace810180546001600160a01b039093166001600160a01b03199093169290921790915594517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5acf86015592517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad085015591517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad19093018054995115156101000261ff00199415159490941661ffff19909a16999099179290921790975582815260038252848120805494850181558152818120909301859055835188815290810187905292830191909152919283917f1ad1a5ae4ffda7ac4728a3f999d312ee8c3bf93f8f9bec6ea55609ec2980c0d7910160405180910390a392915050565b60028181548110610807575f80fd5b5f91825260209091206004909102018054600182015460028301546003909301546001600160a01b039092169350919060ff8082169161010090041685565b5f80670de0b6b3a764000061085b8486610cca565b6108659190610ce7565b90505f81116108a25760405162461bcd60e51b81526020600482015260096024820152681e995c9bc818dbdcdd60ba1b6044820152606401610213565b6001546108ba906001600160a01b0316333084610b1c565b600280546040805160a0810182523380825260208083018a81528385018a81526001606080870182815260808801838152838b018c555f9b8c52975160048b027f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace810180546001600160a01b039093166001600160a01b03199093169290921790915594517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5acf86015592517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad085015591517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad19093018054965115156101000261ff00199415159490941661ffff19909716969096179290921790945582875260038252848720805480830182559088529682902090960185905583518a81529081018990529283019490945291945084917f1ad1a5ae4ffda7ac4728a3f999d312ee8c3bf93f8f9bec6ea55609ec2980c0d7910160405180910390a35092915050565b6040516001600160a01b038381166024830152604482018390525f919085169060640160408051601f198184030181529181526020820180516001600160e01b031663a9059cbb60e01b17905251610a959190610d19565b5f604051808303815f865af19150503d805f8114610ace576040519150601f19603f3d011682016040523d82523d5f602084013e610ad3565b606091505b5050905080610b165760405162461bcd60e51b815260206004820152600f60248201526e1d1c985b9cd9995c8819985a5b1959608a1b6044820152606401610213565b50505050565b6040516001600160a01b0384811660248301528381166044830152606482018390525f919086169060840160408051601f198184030181529181526020820180516001600160e01b03166323b872dd60e01b17905251610b7c9190610d19565b5f604051808303815f865af19150503d805f8114610bb5576040519150601f19603f3d011682016040523d82523d5f602084013e610bba565b606091505b5050905080610c015760405162461bcd60e51b81526020600482015260136024820152721d1c985b9cd9995c919c9bdb4819985a5b1959606a1b6044820152606401610213565b5050505050565b5f8060408385031215610c19575f80fd5b50508035926020909101359150565b80356001600160a01b0381168114610c3e575f80fd5b919050565b5f60208284031215610c53575f80fd5b610c5c82610c28565b9392505050565b5f60208284031215610c73575f80fd5b5035919050565b5f8060408385031215610c8b575f80fd5b610c9483610c28565b946020939093013593505050565b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52601160045260245ffd5b8082028115828204841417610ce157610ce1610cb6565b92915050565b5f82610d0157634e487b7160e01b5f52601260045260245ffd5b500490565b81810381811115610ce157610ce1610cb6565b5f82518060208501845e5f92019182525091905056fea2646970667358221220a634b8b68f363ef67e6bcaa164b9c106c2574a04d912695c7890cd3c1501b01a64736f6c634300081a0033" + +## setup: mint BaseToken to all spammer accounts ################################## + +[[setup]] +kind = "spammer_mint_base" +to = "{BaseToken}" +from_pool = "spammers" +for_all_accounts = true +signature = "mint(address to, uint256 amount)" +args = ["{_sender}", "100000000000000000000000"] + +## setup: mint QuoteToken to all spammer accounts ################################# + +[[setup]] +kind = "spammer_mint_quote" +to = "{QuoteToken}" +from_pool = "spammers" +for_all_accounts = true +signature = "mint(address to, uint256 amount)" +args = ["{_sender}", "100000000000000000000000"] + +## setup: all spammer accounts approve OrderBook for BaseToken #################### + +[[setup]] +kind = "spammer_approve_base" +to = "{BaseToken}" +from_pool = "spammers" +for_all_accounts = true +signature = "approve(address spender, uint256 amount) returns (bool)" +args = [ + "{OrderBook}", + "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", +] + +## setup: all spammer accounts approve OrderBook for QuoteToken ################### + +[[setup]] +kind = "spammer_approve_quote" +to = "{QuoteToken}" +from_pool = "spammers" +for_all_accounts = true +signature = "approve(address spender, uint256 amount) returns (bool)" +args = [ + "{OrderBook}", + "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", +] + +### SPAM + +## spam: place buy orders (fuzz price and amount) ################################# + +[[spam]] +[spam.tx] +kind = "place_buy_order" +to = "{OrderBook}" +from_pool = "spammers" +signature = "placeBuyOrder(uint256 price, uint256 amount) returns (uint256 orderId)" +args = ["1000000000000000000", "1000000000000000"] +gas_limit = 300000 +fuzz = [ + { param = "price", min = "1000000000000000", max = "1000000000000000000" }, + { param = "amount", min = "1000000000000000", max = "100000000000000000" }, +] + +## spam: place sell orders (fuzz price and amount) ################################ + +[[spam]] +[spam.tx] +kind = "place_sell_order" +to = "{OrderBook}" +from_pool = "spammers" +signature = "placeSellOrder(uint256 price, uint256 amount) returns (uint256 orderId)" +args = ["1000000000000000000", "1000000000000000"] +gas_limit = 300000 +fuzz = [ + { param = "price", min = "1000000000000000", max = "1000000000000000000" }, + { param = "amount", min = "1000000000000000", max = "100000000000000000" }, +] + +## spam: cancel orders (fuzz orderId, may revert for invalid/already-cancelled) ### + +[[spam]] +[spam.tx] +kind = "cancel_order" +to = "{OrderBook}" +from_pool = "spammers" +signature = "cancelOrder(uint256 orderId)" +args = ["0"] +gas_limit = 200000 +fuzz = [{ param = "orderId", min = "0", max = "1000" }] diff --git a/scenarios/precompiles/hashPrecompiles.toml b/scenarios/precompiles/hashPrecompiles.toml new file mode 100644 index 00000000..e2f11320 --- /dev/null +++ b/scenarios/precompiles/hashPrecompiles.toml @@ -0,0 +1,50 @@ +# Focused precompile stress test: SHA256, RIPEMD160, identity, and batch calls. +# Contract: PrecompileHammer (Solidity 0.8.26, optimized) + +[[create]] +name = "PrecompileHammer" +bytecode = "0x6080604052348015600e575f80fd5b5061027f8061001c5f395ff3fe608060405234801561000f575f80fd5b506004361061004a575f3560e01c80635a4b5af11461004e5780638ec9117714610063578063a58a5f7f14610076578063c074b16614610089575b5f80fd5b61006161005c36600461018c565b61009c565b005b61006161007136600461018c565b6100cb565b61006161008436600461018c565b6100f5565b61006161009736600461018c565b61011f565b60045f5b838110156100c55782515f8160208601855afa806100bc575f80fd5b506001016100a0565b50505050565b60025f5b838110156100c55760205f845160208601855afa806100ec575f80fd5b506001016100cf565b60035f5b838110156100c55760205f845160208601855afa80610116575f80fd5b506001016100f9565b5f5b828110156101735781516020830160205f838360025afa80610141575f80fd5b60205f848460035afa905080610155575f80fd5b825f848460045afa905080610168575f80fd5b505050600101610121565b505050565b634e487b7160e01b5f52604160045260245ffd5b5f806040838503121561019d575f80fd5b82359150602083013567ffffffffffffffff8111156101ba575f80fd5b8301601f810185136101ca575f80fd5b803567ffffffffffffffff8111156101e4576101e4610178565b604051601f8201601f19908116603f0116810167ffffffffffffffff8111828210171561021357610213610178565b60405281815282820160200187101561022a575f80fd5b816020840160208301375f60208383010152809350505050925092905056fea26469706673582212209e3c9c53805c700a69bd48aac177fa8f0cd631f448c2aec5ce07bdd5c24b1b0664736f6c634300081a0033" + +# SHA256 precompile (0x02) stress +[[spam]] +from_pool = "sha256_pool" +[spam.tx] +to = "{PrecompileHammer}" +signature = "hashSHA256(uint256 iterations, bytes memory data)" +args = ["200", "0xdeadbeef"] +fuzz = [ + { param = "iterations", min = "100", max = "500" }, +] + +# RIPEMD160 precompile (0x03) stress +[[spam]] +from_pool = "ripemd160_pool" +[spam.tx] +to = "{PrecompileHammer}" +signature = "hashRIPEMD160(uint256 iterations2, bytes memory data2)" +args = ["200", "0xdeadbeef"] +fuzz = [ + { param = "iterations2", min = "100", max = "500" }, +] + +# Identity precompile (0x04) stress — cheaper per call, so higher iteration range +[[spam]] +from_pool = "identity_pool" +[spam.tx] +to = "{PrecompileHammer}" +signature = "callIdentity(uint256 iterations3, bytes memory data3)" +args = ["1000", "0xdeadbeef"] +fuzz = [ + { param = "iterations3", min = "500", max = "2000" }, +] + +# Batch all three precompiles per iteration +[[spam]] +from_pool = "batch_pool" +[spam.tx] +to = "{PrecompileHammer}" +signature = "batchPrecompiles(uint256 iterations4, bytes memory data4)" +args = ["100", "0xdeadbeef"] +fuzz = [ + { param = "iterations4", min = "50", max = "200" }, +] diff --git a/scenarios/simpleAMM.toml b/scenarios/simpleAMM.toml new file mode 100644 index 00000000..1486ad2f --- /dev/null +++ b/scenarios/simpleAMM.toml @@ -0,0 +1,134 @@ +# Simple AMM (Constant Product Market Maker) scenario +# +# Deploys a simplified Uniswap V2-style AMM with two ERC20 tokens. +# Tests the classic AMM gas pattern: reserve reads, balance updates, +# fee calculations (0.3%), and the x*y=k invariant. +# +# Contracts: +# - AMMToken: Minimal ERC20 with public mint +# - SimpleAMM: Constant product AMM with addLiquidity, removeLiquidity, swapAForB, swapBForA +# - AMMHelper: Holds tokens and proxies swap/liquidity calls (so spammers don't need token balances) +# +# source: /tmp/amm.sol +# compiled with: solc --bin --optimize --optimize-runs 200 /tmp/amm.sol + +[env] +initialSupply = "1000000000000000000000000000" +liquidityAmount = "100000000000000000000000" +helperFunds = "500000000000000000000000" + + +### Deploy contracts ########################################################### + +[[create]] +name = "TokenA" +signature = "(string memory name_, uint256 initialSupply)" +args = ["TokenA", "{initialSupply}"] +# AMMToken bytecode +bytecode = "0x608060405234801561000f575f80fd5b5060405161091438038061091483398101604081905261002e916100aa565b5f61003983826101e2565b50600161004683826101e2565b506002819055335f818152600360209081526040808320859055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3505061029c565b634e487b7160e01b5f52604160045260245ffd5b5f80604083850312156100bb575f80fd5b82516001600160401b038111156100d0575f80fd5b8301601f810185136100e0575f80fd5b80516001600160401b038111156100f9576100f9610096565b604051601f8201601f19908116603f011681016001600160401b038111828210171561012757610127610096565b60405281815282820160200187101561013e575f80fd5b8160208401602083015e5f60209282018301529401519395939450505050565b600181811c9082168061017257607f821691505b60208210810361019057634e487b7160e01b5f52602260045260245ffd5b50919050565b601f8211156101dd57805f5260205f20601f840160051c810160208510156101bb5750805b601f840160051c820191505b818110156101da575f81556001016101c7565b50505b505050565b81516001600160401b038111156101fb576101fb610096565b61020f81610209845461015e565b84610196565b6020601f821160018114610241575f831561022a5750848201515b5f19600385901b1c1916600184901b1784556101da565b5f84815260208120601f198516915b828110156102705787850151825560209485019460019092019101610250565b508482101561028d57868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b61066b806102a95f395ff3fe608060405234801561000f575f80fd5b506004361061009b575f3560e01c806340c10f191161006357806340c10f191461012457806370a082311461013957806395d89b4114610158578063a9059cbb14610160578063dd62ed3e14610173575f80fd5b806306fdde031461009f578063095ea7b3146100bd57806318160ddd146100e057806323b872dd146100f7578063313ce5671461010a575b5f80fd5b6100a761019d565b6040516100b491906104c0565b60405180910390f35b6100d06100cb366004610510565b610228565b60405190151581526020016100b4565b6100e960025481565b6040519081526020016100b4565b6100d0610105366004610538565b610294565b610112601281565b60405160ff90911681526020016100b4565b610137610132366004610510565b61039f565b005b6100e9610147366004610572565b60036020525f908152604090205481565b6100a7610425565b6100d061016e366004610510565b610432565b6100e9610181366004610592565b600460209081525f928352604080842090915290825290205481565b5f80546101a9906105c3565b80601f01602080910402602001604051908101604052809291908181526020018280546101d5906105c3565b80156102205780601f106101f757610100808354040283529160200191610220565b820191905f5260205f20905b81548152906001019060200180831161020357829003601f168201915b505050505081565b335f8181526004602090815260408083206001600160a01b038716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925906102829086815260200190565b60405180910390a35060015b92915050565b6001600160a01b0383165f9081526004602090815260408083203384529091528120545f1981146102ed576102c9838261060f565b6001600160a01b0386165f9081526004602090815260408083203384529091529020555b6001600160a01b0385165f908152600360205260408120805485929061031490849061060f565b90915550506001600160a01b0384165f9081526003602052604081208054859290610340908490610622565b92505081905550836001600160a01b0316856001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8560405161038c91815260200190565b60405180910390a3506001949350505050565b8060025f8282546103b09190610622565b90915550506001600160a01b0382165f90815260036020526040812080548392906103dc908490610622565b90915550506040518181526001600160a01b038316905f907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b600180546101a9906105c3565b335f9081526003602052604081208054839190839061045290849061060f565b90915550506001600160a01b0383165f908152600360205260408120805484929061047e908490610622565b90915550506040518281526001600160a01b0384169033907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602001610282565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f83011684010191505092915050565b80356001600160a01b038116811461050b575f80fd5b919050565b5f8060408385031215610521575f80fd5b61052a836104f5565b946020939093013593505050565b5f805f6060848603121561054a575f80fd5b610553846104f5565b9250610561602085016104f5565b929592945050506040919091013590565b5f60208284031215610582575f80fd5b61058b826104f5565b9392505050565b5f80604083850312156105a3575f80fd5b6105ac836104f5565b91506105ba602084016104f5565b90509250929050565b600181811c908216806105d757607f821691505b6020821081036105f557634e487b7160e01b5f52602260045260245ffd5b50919050565b634e487b7160e01b5f52601160045260245ffd5b8181038181111561028e5761028e6105fb565b8082018082111561028e5761028e6105fb56fea2646970667358221220a8d5495695df06a2a563b3bc279a5798a51e98b9a8544c4d41f799388eba790764736f6c634300081a0033" + +[[create]] +name = "TokenB" +signature = "(string memory name_, uint256 initialSupply)" +args = ["TokenB", "{initialSupply}"] +# AMMToken bytecode (same contract, different constructor args) +bytecode = "0x608060405234801561000f575f80fd5b5060405161091438038061091483398101604081905261002e916100aa565b5f61003983826101e2565b50600161004683826101e2565b506002819055335f818152600360209081526040808320859055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3505061029c565b634e487b7160e01b5f52604160045260245ffd5b5f80604083850312156100bb575f80fd5b82516001600160401b038111156100d0575f80fd5b8301601f810185136100e0575f80fd5b80516001600160401b038111156100f9576100f9610096565b604051601f8201601f19908116603f011681016001600160401b038111828210171561012757610127610096565b60405281815282820160200187101561013e575f80fd5b8160208401602083015e5f60209282018301529401519395939450505050565b600181811c9082168061017257607f821691505b60208210810361019057634e487b7160e01b5f52602260045260245ffd5b50919050565b601f8211156101dd57805f5260205f20601f840160051c810160208510156101bb5750805b601f840160051c820191505b818110156101da575f81556001016101c7565b50505b505050565b81516001600160401b038111156101fb576101fb610096565b61020f81610209845461015e565b84610196565b6020601f821160018114610241575f831561022a5750848201515b5f19600385901b1c1916600184901b1784556101da565b5f84815260208120601f198516915b828110156102705787850151825560209485019460019092019101610250565b508482101561028d57868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b61066b806102a95f395ff3fe608060405234801561000f575f80fd5b506004361061009b575f3560e01c806340c10f191161006357806340c10f191461012457806370a082311461013957806395d89b4114610158578063a9059cbb14610160578063dd62ed3e14610173575f80fd5b806306fdde031461009f578063095ea7b3146100bd57806318160ddd146100e057806323b872dd146100f7578063313ce5671461010a575b5f80fd5b6100a761019d565b6040516100b491906104c0565b60405180910390f35b6100d06100cb366004610510565b610228565b60405190151581526020016100b4565b6100e960025481565b6040519081526020016100b4565b6100d0610105366004610538565b610294565b610112601281565b60405160ff90911681526020016100b4565b610137610132366004610510565b61039f565b005b6100e9610147366004610572565b60036020525f908152604090205481565b6100a7610425565b6100d061016e366004610510565b610432565b6100e9610181366004610592565b600460209081525f928352604080842090915290825290205481565b5f80546101a9906105c3565b80601f01602080910402602001604051908101604052809291908181526020018280546101d5906105c3565b80156102205780601f106101f757610100808354040283529160200191610220565b820191905f5260205f20905b81548152906001019060200180831161020357829003601f168201915b505050505081565b335f8181526004602090815260408083206001600160a01b038716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925906102829086815260200190565b60405180910390a35060015b92915050565b6001600160a01b0383165f9081526004602090815260408083203384529091528120545f1981146102ed576102c9838261060f565b6001600160a01b0386165f9081526004602090815260408083203384529091529020555b6001600160a01b0385165f908152600360205260408120805485929061031490849061060f565b90915550506001600160a01b0384165f9081526003602052604081208054859290610340908490610622565b92505081905550836001600160a01b0316856001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8560405161038c91815260200190565b60405180910390a3506001949350505050565b8060025f8282546103b09190610622565b90915550506001600160a01b0382165f90815260036020526040812080548392906103dc908490610622565b90915550506040518181526001600160a01b038316905f907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b600180546101a9906105c3565b335f9081526003602052604081208054839190839061045290849061060f565b90915550506001600160a01b0383165f908152600360205260408120805484929061047e908490610622565b90915550506040518281526001600160a01b0384169033907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602001610282565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f83011684010191505092915050565b80356001600160a01b038116811461050b575f80fd5b919050565b5f8060408385031215610521575f80fd5b61052a836104f5565b946020939093013593505050565b5f805f6060848603121561054a575f80fd5b610553846104f5565b9250610561602085016104f5565b929592945050506040919091013590565b5f60208284031215610582575f80fd5b61058b826104f5565b9392505050565b5f80604083850312156105a3575f80fd5b6105ac836104f5565b91506105ba602084016104f5565b90509250929050565b600181811c908216806105d757607f821691505b6020821081036105f557634e487b7160e01b5f52602260045260245ffd5b50919050565b634e487b7160e01b5f52601160045260245ffd5b8181038181111561028e5761028e6105fb565b8082018082111561028e5761028e6105fb56fea2646970667358221220a8d5495695df06a2a563b3bc279a5798a51e98b9a8544c4d41f799388eba790764736f6c634300081a0033" + +[[create]] +name = "SimpleAMM" +signature = "(address tokenA_, address tokenB_)" +args = ["{TokenA}", "{TokenB}"] +# SimpleAMM bytecode +bytecode = "0x6080604052348015600e575f80fd5b50604051610ca3380380610ca3833981016040819052602b916074565b5f80546001600160a01b039384166001600160a01b0319918216179091556001805492909316911617905560a0565b80516001600160a01b0381168114606f575f80fd5b919050565b5f80604083850312156084575f80fd5b608b83605a565b9150609760208401605a565b90509250929050565b610bf6806100ad5f395ff3fe608060405234801561000f575f80fd5b506004361061009b575f3560e01c806370a082311161006357806370a08231146101145780639c8f9f23146101335780639cd441da1461015b578063dc5fa6c51461016e578063e619a49814610177575f80fd5b8063031020911461009f5780630fc63d10146100c557806318160ddd146100ef57806319e36f3b146100f85780635f64b55b14610101575b5f80fd5b6100b26100ad366004610aa3565b61018a565b6040519081526020015b60405180910390f35b5f546100d7906001600160a01b031681565b6040516001600160a01b0390911681526020016100bc565b6100b260045481565b6100b260035481565b6001546100d7906001600160a01b031681565b6100b2610122366004610aba565b60056020525f908152604090205481565b610146610141366004610aa3565b6103ac565b604080519283526020830191909152016100bc565b6100b2610169366004610ae7565b6105d8565b6100b260025481565b6100b2610185366004610aa3565b610823565b5f8082116101cc5760405162461bcd60e51b815260206004820152600a6024820152691e995c9bc81a5b9c1d5d60b21b60448201526064015b60405180910390fd5b5f546040516323b872dd60e01b81526001600160a01b03909116906323b872dd906101ff90339030908790600401610b07565b6020604051808303815f875af115801561021b573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061023f9190610b2b565b505f61024d836103e5610b5e565b9050806002546103e86102609190610b5e565b61026a9190610b7b565b6003546102779083610b5e565b6102819190610b8e565b91505f82116102c05760405162461bcd60e51b815260206004820152600b60248201526a1e995c9bc81bdd5d1c1d5d60aa1b60448201526064016101c3565b8260025f8282546102d19190610b7b565b925050819055508160035f8282546102e99190610bad565b909155505060015460405163a9059cbb60e01b8152336004820152602481018490526001600160a01b039091169063a9059cbb906044016020604051808303815f875af115801561033c573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906103609190610b2b565b5060408051600181526020810185905290810183905233907fbfd50a04f1e6e4aee344f5d0e7f15d74d0dbb58cd1f711daa6463094ca9508cd906060015b60405180910390a250919050565b5f805f831180156103cb5750335f908152600560205260409020548311155b6104045760405162461bcd60e51b815260206004820152600a6024820152696261642073686172657360b01b60448201526064016101c3565b6004546002546104149085610b5e565b61041e9190610b8e565b9150600454600354846104319190610b5e565b61043b9190610b8e565b335f9081526005602052604081208054929350859290919061045e908490610bad565b925050819055508260045f8282546104769190610bad565b925050819055508160025f82825461048e9190610bad565b925050819055508060035f8282546104a69190610bad565b90915550505f5460405163a9059cbb60e01b8152336004820152602481018490526001600160a01b039091169063a9059cbb906044016020604051808303815f875af11580156104f8573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061051c9190610b2b565b5060015460405163a9059cbb60e01b8152336004820152602481018390526001600160a01b039091169063a9059cbb906044016020604051808303815f875af115801561056b573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061058f9190610b2b565b50604080518381526020810183905290810184905233907f59c3a0b60c6ab7deb62e1440c9e72441db6db7dfe514dba8cb18e60c0d896efa9060600160405180910390a2915091565b5f80546040516323b872dd60e01b81526001600160a01b03909116906323b872dd9061060c90339030908890600401610b07565b6020604051808303815f875af1158015610628573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061064c9190610b2b565b506001546040516323b872dd60e01b81526001600160a01b03909116906323b872dd9061068190339030908790600401610b07565b6020604051808303815f875af115801561069d573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906106c19190610b2b565b506004545f036106e4576106dd6106d88385610b5e565b610a35565b9050610734565b5f600254600454856106f69190610b5e565b6107009190610b8e565b90505f600354600454856107149190610b5e565b61071e9190610b8e565b905080821061072d578061072f565b815b925050505b5f81116107715760405162461bcd60e51b815260206004820152600b60248201526a7a65726f2073686172657360a81b60448201526064016101c3565b8060045f8282546107829190610b7b565b9091555050335f90815260056020526040812080548392906107a5908490610b7b565b925050819055508260025f8282546107bd9190610b7b565b925050819055508160035f8282546107d59190610b7b565b9091555050604080518481526020810184905290810182905233907fbeb3885786d637a474cbc287c0a44587231633a077f0bd30354d5a4b18996fce9060600160405180910390a292915050565b5f8082116108605760405162461bcd60e51b815260206004820152600a6024820152691e995c9bc81a5b9c1d5d60b21b60448201526064016101c3565b6001546040516323b872dd60e01b81526001600160a01b03909116906323b872dd9061089490339030908790600401610b07565b6020604051808303815f875af11580156108b0573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108d49190610b2b565b505f6108e2836103e5610b5e565b9050806003546103e86108f59190610b5e565b6108ff9190610b7b565b60025461090c9083610b5e565b6109169190610b8e565b91505f82116109555760405162461bcd60e51b815260206004820152600b60248201526a1e995c9bc81bdd5d1c1d5d60aa1b60448201526064016101c3565b8260035f8282546109669190610b7b565b925050819055508160025f82825461097e9190610bad565b90915550505f5460405163a9059cbb60e01b8152336004820152602481018490526001600160a01b039091169063a9059cbb906044016020604051808303815f875af11580156109d0573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109f49190610b2b565b50604080515f81526020810185905290810183905233907fbfd50a04f1e6e4aee344f5d0e7f15d74d0dbb58cd1f711daa6463094ca9508cd9060600161039e565b5f6003821115610a945750805f610a4d600283610b8e565b610a58906001610b7b565b90505b81811015610a8e57905080600281610a738186610b8e565b610a7d9190610b7b565b610a879190610b8e565b9050610a5b565b50919050565b8115610a9e575060015b919050565b5f60208284031215610ab3575f80fd5b5035919050565b5f60208284031215610aca575f80fd5b81356001600160a01b0381168114610ae0575f80fd5b9392505050565b5f8060408385031215610af8575f80fd5b50508035926020909101359150565b6001600160a01b039384168152919092166020820152604081019190915260600190565b5f60208284031215610b3b575f80fd5b81518015158114610ae0575f80fd5b634e487b7160e01b5f52601160045260245ffd5b8082028115828204841417610b7557610b75610b4a565b92915050565b80820180821115610b7557610b75610b4a565b5f82610ba857634e487b7160e01b5f52601260045260245ffd5b500490565b81810381811115610b7557610b75610b4a56fea2646970667358221220858eea2e622314367c3acccbe6b546097815224fd777af4fca336bf48dd6152664736f6c634300081a0033" + +[[create]] +name = "AMMHelper" +signature = "(address amm_, address tokenA_, address tokenB_)" +args = ["{SimpleAMM}", "{TokenA}", "{TokenB}"] +# AMMHelper bytecode - holds tokens, proxies swaps so spammers don't need token balances +bytecode = "0x608060405234801561000f575f80fd5b5060405161047d38038061047d83398101604081905261002e91610168565b5f80546001600160a01b03199081166001600160a01b03868116918217909355600180548316868516908117909155600280549093169385169390931790915560405163095ea7b360e01b815260048101919091525f19602482015263095ea7b3906044016020604051808303815f875af11580156100af573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906100d391906101a8565b5060405163095ea7b360e01b81526001600160a01b0384811660048301525f19602483015282169063095ea7b3906044016020604051808303815f875af1158015610120573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061014491906101a8565b505050506101ce565b80516001600160a01b0381168114610163575f80fd5b919050565b5f805f6060848603121561017a575f80fd5b6101838461014d565b92506101916020850161014d565b915061019f6040850161014d565b90509250925092565b5f602082840312156101b8575f80fd5b815180151581146101c7575f80fd5b9392505050565b6102a2806101db5f395ff3fe608060405234801561000f575f80fd5b5060043610610060575f3560e01c806303102091146100645780630fc63d101461008a5780632a943945146100b55780635f64b55b146100c75780639cd441da146100da578063e619a498146100ed575b5f80fd5b61007761007236600461021e565b610100565b6040519081526020015b60405180910390f35b60015461009d906001600160a01b031681565b6040516001600160a01b039091168152602001610081565b5f5461009d906001600160a01b031681565b60025461009d906001600160a01b031681565b6100776100e8366004610235565b610173565b6100776100fb36600461021e565b6101ed565b5f8054604051630310209160e01b8152600481018490526001600160a01b03909116906303102091906024015b6020604051808303815f875af1158015610149573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061016d9190610255565b92915050565b5f8054604051634e6a20ed60e11b815260048101859052602481018490526001600160a01b0390911690639cd441da906044016020604051808303815f875af11580156101c2573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906101e69190610255565b9392505050565b5f8054604051631cc3349360e31b8152600481018490526001600160a01b039091169063e619a4989060240161012d565b5f6020828403121561022e575f80fd5b5035919050565b5f8060408385031215610246575f80fd5b50508035926020909101359150565b5f60208284031215610265575f80fd5b505191905056fea264697066735822122076cfb1aa07cb66669e43005b5f038e2061e4c97003cb560568e8312e7317bf6e64736f6c634300081a0033" + + +### Setup contracts ############################################################# + +## Approve AMM to spend admin's tokens (for initial liquidity) + +[[setup]] +kind = "admin_approve_amm_tokenA" +to = "{TokenA}" +signature = "approve(address spender, uint256 amount) returns (bool)" +args = [ + "{SimpleAMM}", + "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", +] + +[[setup]] +kind = "admin_approve_amm_tokenB" +to = "{TokenB}" +signature = "approve(address spender, uint256 amount) returns (bool)" +args = [ + "{SimpleAMM}", + "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", +] + +## Add initial liquidity (large amounts for deep pool) + +[[setup]] +kind = "admin_add_initial_liquidity" +to = "{SimpleAMM}" +signature = "addLiquidity(uint256 amountA, uint256 amountB) returns (uint256 shares)" +args = ["{liquidityAmount}", "{liquidityAmount}"] +gas_limit = 300000 + +## Fund the AMMHelper contract with tokens for spammer swaps + +[[setup]] +kind = "fund_helper_tokenA" +to = "{TokenA}" +signature = "function transfer(address to, uint256 amount) external returns (bool)" +args = ["{AMMHelper}", "{helperFunds}"] + +[[setup]] +kind = "fund_helper_tokenB" +to = "{TokenB}" +signature = "function transfer(address to, uint256 amount) external returns (bool)" +args = ["{AMMHelper}", "{helperFunds}"] + + +### Spam patterns ############################################################## + +# Swap TokenA for TokenB via helper (spammers don't need token balances) +# Fuzz amountIn from 0.001 to 1 token (1e15 to 1e18 wei) +[[spam]] +[spam.tx] +kind = "simple_amm_swap_a_for_b" +to = "{AMMHelper}" +from_pool = "spammer" +signature = "function swapAForB(uint256 amountIn) external returns (uint256)" +args = ["1000000000000000"] +fuzz = [{ param = "amountIn", min = "1000000000000000", max = "1000000000000000000" }] + +# Swap TokenB for TokenA via helper +# Fuzz amountIn from 0.001 to 1 token (1e15 to 1e18 wei) +[[spam]] +[spam.tx] +kind = "simple_amm_swap_b_for_a" +to = "{AMMHelper}" +from_pool = "spammer" +signature = "function swapBForA(uint256 amountIn) external returns (uint256)" +args = ["1000000000000000"] +fuzz = [{ param = "amountIn", min = "1000000000000000", max = "1000000000000000000" }] + +# Add liquidity via helper (smaller amounts to avoid draining helper funds) +# Fuzz both amounts from 0.001 to 0.01 tokens +[[spam]] +[spam.tx] +kind = "simple_amm_add_liquidity" +to = "{AMMHelper}" +from_pool = "spammer" +signature = "function addLiquidity(uint256 amountA, uint256 amountB) external returns (uint256)" +args = ["1000000000000000", "1000000000000000"] +fuzz = [ + { param = "amountA", min = "1000000000000000", max = "10000000000000000" }, + { param = "amountB", min = "1000000000000000", max = "10000000000000000" }, +] diff --git a/scenarios/stableSwap.toml b/scenarios/stableSwap.toml new file mode 100644 index 00000000..61990fc6 --- /dev/null +++ b/scenarios/stableSwap.toml @@ -0,0 +1,165 @@ +# Curve-style StableSwap AMM scenario +# +# Deploys a Curve-inspired 2-token stable pool with the StableSwap invariant. +# Unlike constant-product AMMs (x*y=k), StableSwap uses an invariant that blends +# constant-sum and constant-product behavior, controlled by the amplification +# coefficient A. The key gas differentiator is Newton's method iteration (up to +# 255 iterations) in both getD() and getY(), making swaps ~2-3x more expensive +# than constant-product AMMs. This represents ~1.5% of mainnet gas. +# +# Contracts: +# - StableToken: Minimal ERC20 with public mint +# - StableSwap: Curve-style 2-token pool with Newton's method invariant +# +# source: /tmp/stableswap.sol +# compiled with: solc --bin --optimize --optimize-runs 200 /tmp/stableswap.sol + +[env] +initialSupply = "1000000000000000000000000000" +amplification = "100" +liquidityAmount = "1000000000000000000000000" +spammerFunds = "100000000000000000000000" + + +### Deploy contracts ########################################################### + +[[create]] +name = "TokenA" +signature = "(uint256 initialSupply)" +args = ["{initialSupply}"] +# StableToken bytecode +bytecode = "0x608060405234801561000f575f80fd5b506040516108b33803806108b383398101604081905261002e916100d2565b60408051808201909152600b81526a29ba30b13632aa37b5b2b760a91b60208201525f9061005c9082610181565b5060408051808201909152600281526114d560f21b60208201526001906100839082610181565b506002819055335f818152600360209081526040808320859055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35061023b565b5f602082840312156100e2575f80fd5b5051919050565b634e487b7160e01b5f52604160045260245ffd5b600181811c9082168061011157607f821691505b60208210810361012f57634e487b7160e01b5f52602260045260245ffd5b50919050565b601f82111561017c57805f5260205f20601f840160051c8101602085101561015a5750805b601f840160051c820191505b81811015610179575f8155600101610166565b50505b505050565b81516001600160401b0381111561019a5761019a6100e9565b6101ae816101a884546100fd565b84610135565b6020601f8211600181146101e0575f83156101c95750848201515b5f19600385901b1c1916600184901b178455610179565b5f84815260208120601f198516915b8281101561020f57878501518255602094850194600190920191016101ef565b508482101561022c57868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b61066b806102485f395ff3fe608060405234801561000f575f80fd5b506004361061009b575f3560e01c806340c10f191161006357806340c10f191461012457806370a082311461013957806395d89b4114610158578063a9059cbb14610160578063dd62ed3e14610173575f80fd5b806306fdde031461009f578063095ea7b3146100bd57806318160ddd146100e057806323b872dd146100f7578063313ce5671461010a575b5f80fd5b6100a761019d565b6040516100b491906104c0565b60405180910390f35b6100d06100cb366004610510565b610228565b60405190151581526020016100b4565b6100e960025481565b6040519081526020016100b4565b6100d0610105366004610538565b610294565b610112601281565b60405160ff90911681526020016100b4565b610137610132366004610510565b61039f565b005b6100e9610147366004610572565b60036020525f908152604090205481565b6100a7610425565b6100d061016e366004610510565b610432565b6100e9610181366004610592565b600460209081525f928352604080842090915290825290205481565b5f80546101a9906105c3565b80601f01602080910402602001604051908101604052809291908181526020018280546101d5906105c3565b80156102205780601f106101f757610100808354040283529160200191610220565b820191905f5260205f20905b81548152906001019060200180831161020357829003601f168201915b505050505081565b335f8181526004602090815260408083206001600160a01b038716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925906102829086815260200190565b60405180910390a35060015b92915050565b6001600160a01b0383165f9081526004602090815260408083203384529091528120545f1981146102ed576102c9838261060f565b6001600160a01b0386165f9081526004602090815260408083203384529091529020555b6001600160a01b0385165f908152600360205260408120805485929061031490849061060f565b90915550506001600160a01b0384165f9081526003602052604081208054859290610340908490610622565b92505081905550836001600160a01b0316856001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8560405161038c91815260200190565b60405180910390a3506001949350505050565b8060025f8282546103b09190610622565b90915550506001600160a01b0382165f90815260036020526040812080548392906103dc908490610622565b90915550506040518181526001600160a01b038316905f907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b600180546101a9906105c3565b335f9081526003602052604081208054839190839061045290849061060f565b90915550506001600160a01b0383165f908152600360205260408120805484929061047e908490610622565b90915550506040518281526001600160a01b0384169033907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602001610282565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f83011684010191505092915050565b80356001600160a01b038116811461050b575f80fd5b919050565b5f8060408385031215610521575f80fd5b61052a836104f5565b946020939093013593505050565b5f805f6060848603121561054a575f80fd5b610553846104f5565b9250610561602085016104f5565b929592945050506040919091013590565b5f60208284031215610582575f80fd5b61058b826104f5565b9392505050565b5f80604083850312156105a3575f80fd5b6105ac836104f5565b91506105ba602084016104f5565b90509250929050565b600181811c908216806105d757607f821691505b6020821081036105f557634e487b7160e01b5f52602260045260245ffd5b50919050565b634e487b7160e01b5f52601160045260245ffd5b8181038181111561028e5761028e6105fb565b8082018082111561028e5761028e6105fb56fea2646970667358221220c82454eeb2d8ceccfb04098094fb3f978ca85478e36291c91a692f2c9d2185a064736f6c634300081a0033" + +[[create]] +name = "TokenB" +signature = "(uint256 initialSupply)" +args = ["{initialSupply}"] +# StableToken bytecode (same contract, different deployment) +bytecode = "0x608060405234801561000f575f80fd5b506040516108b33803806108b383398101604081905261002e916100d2565b60408051808201909152600b81526a29ba30b13632aa37b5b2b760a91b60208201525f9061005c9082610181565b5060408051808201909152600281526114d560f21b60208201526001906100839082610181565b506002819055335f818152600360209081526040808320859055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35061023b565b5f602082840312156100e2575f80fd5b5051919050565b634e487b7160e01b5f52604160045260245ffd5b600181811c9082168061011157607f821691505b60208210810361012f57634e487b7160e01b5f52602260045260245ffd5b50919050565b601f82111561017c57805f5260205f20601f840160051c8101602085101561015a5750805b601f840160051c820191505b81811015610179575f8155600101610166565b50505b505050565b81516001600160401b0381111561019a5761019a6100e9565b6101ae816101a884546100fd565b84610135565b6020601f8211600181146101e0575f83156101c95750848201515b5f19600385901b1c1916600184901b178455610179565b5f84815260208120601f198516915b8281101561020f57878501518255602094850194600190920191016101ef565b508482101561022c57868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b61066b806102485f395ff3fe608060405234801561000f575f80fd5b506004361061009b575f3560e01c806340c10f191161006357806340c10f191461012457806370a082311461013957806395d89b4114610158578063a9059cbb14610160578063dd62ed3e14610173575f80fd5b806306fdde031461009f578063095ea7b3146100bd57806318160ddd146100e057806323b872dd146100f7578063313ce5671461010a575b5f80fd5b6100a761019d565b6040516100b491906104c0565b60405180910390f35b6100d06100cb366004610510565b610228565b60405190151581526020016100b4565b6100e960025481565b6040519081526020016100b4565b6100d0610105366004610538565b610294565b610112601281565b60405160ff90911681526020016100b4565b610137610132366004610510565b61039f565b005b6100e9610147366004610572565b60036020525f908152604090205481565b6100a7610425565b6100d061016e366004610510565b610432565b6100e9610181366004610592565b600460209081525f928352604080842090915290825290205481565b5f80546101a9906105c3565b80601f01602080910402602001604051908101604052809291908181526020018280546101d5906105c3565b80156102205780601f106101f757610100808354040283529160200191610220565b820191905f5260205f20905b81548152906001019060200180831161020357829003601f168201915b505050505081565b335f8181526004602090815260408083206001600160a01b038716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925906102829086815260200190565b60405180910390a35060015b92915050565b6001600160a01b0383165f9081526004602090815260408083203384529091528120545f1981146102ed576102c9838261060f565b6001600160a01b0386165f9081526004602090815260408083203384529091529020555b6001600160a01b0385165f908152600360205260408120805485929061031490849061060f565b90915550506001600160a01b0384165f9081526003602052604081208054859290610340908490610622565b92505081905550836001600160a01b0316856001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8560405161038c91815260200190565b60405180910390a3506001949350505050565b8060025f8282546103b09190610622565b90915550506001600160a01b0382165f90815260036020526040812080548392906103dc908490610622565b90915550506040518181526001600160a01b038316905f907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b600180546101a9906105c3565b335f9081526003602052604081208054839190839061045290849061060f565b90915550506001600160a01b0383165f908152600360205260408120805484929061047e908490610622565b90915550506040518281526001600160a01b0384169033907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602001610282565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f83011684010191505092915050565b80356001600160a01b038116811461050b575f80fd5b919050565b5f8060408385031215610521575f80fd5b61052a836104f5565b946020939093013593505050565b5f805f6060848603121561054a575f80fd5b610553846104f5565b9250610561602085016104f5565b929592945050506040919091013590565b5f60208284031215610582575f80fd5b61058b826104f5565b9392505050565b5f80604083850312156105a3575f80fd5b6105ac836104f5565b91506105ba602084016104f5565b90509250929050565b600181811c908216806105d757607f821691505b6020821081036105f557634e487b7160e01b5f52602260045260245ffd5b50919050565b634e487b7160e01b5f52601160045260245ffd5b8181038181111561028e5761028e6105fb565b8082018082111561028e5761028e6105fb56fea2646970667358221220c82454eeb2d8ceccfb04098094fb3f978ca85478e36291c91a692f2c9d2185a064736f6c634300081a0033" + +[[create]] +name = "StableSwap" +signature = "(address tokenA_, address tokenB_, uint256 amplification_)" +args = ["{TokenA}", "{TokenB}", "{amplification}"] +# StableSwap bytecode +bytecode = "0x6080604052348015600e575f80fd5b50604051610ebc380380610ebc833981016040819052602b91607b565b5f80546001600160a01b039485166001600160a01b031991821617909155600180549390941692169190911790915560025560af565b80516001600160a01b03811681146076575f80fd5b919050565b5f805f60608486031215608c575f80fd5b6093846061565b9250609f602085016061565b9150604084015190509250925092565b610e00806100bc5f395ff3fe608060405234801561000f575f80fd5b506004361061009b575f3560e01c80639c46665c116100635780639c46665c1461010a5780639c8f9f23146101295780639cd441da146101515780639d9892cd14610164578063f446c1d014610177575f80fd5b80630fc63d101461009f578063132c4feb146100ce578063443cb4bc146100e55780635a76f25e146100ee5780635f64b55b146100f7575b5f80fd5b5f546100b1906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b6100d760065481565b6040519081526020016100c5565b6100d760035481565b6100d760045481565b6001546100b1906001600160a01b031681565b6100d7610118366004610c84565b60056020525f908152604090205481565b61013c610137366004610cb1565b610180565b604080519283526020830191909152016100c5565b6100d761015f366004610cc8565b6102fd565b6100d7610172366004610ce8565b6104f2565b6100d760025481565b5f805f8311801561019f5750335f908152600560205260409020548311155b6101e05760405162461bcd60e51b815260206004820152600d60248201526c189859081b1c08185b5bdd5b9d609a1b60448201526064015b60405180910390fd5b600654836003546101f19190610d25565b6101fb9190610d3c565b91506006548360045461020e9190610d25565b6102189190610d3c565b335f9081526005602052604081208054929350859290919061023b908490610d5b565b925050819055508260065f8282546102539190610d5b565b925050819055508160035f82825461026b9190610d5b565b925050819055508060045f8282546102839190610d5b565b90915550505f5461029e906001600160a01b031633846107a4565b6001546102b5906001600160a01b031633836107a4565b604080518481526020810184905290810182905233907f59c3a0b60c6ab7deb62e1440c9e72441db6db7dfe514dba8cb18e60c0d896efa9060600160405180910390a2915091565b5f8083118061030b57505f82115b6103465760405162461bcd60e51b815260206004820152600c60248201526b7a65726f20616d6f756e747360a01b60448201526064016101d7565b61034e610c66565b600354815260045460208201528315610378575f54610378906001600160a01b03163330876108aa565b821561039657600154610396906001600160a01b03163330866108aa565b61039e610c66565b846003546103ac9190610d82565b81526004546103bc908590610d82565b60208201526006545f036103e0575f6103d7826002546109bd565b93506104259050565b5f6103ed836002546109bd565b90505f6103fc836002546109bd565b9050816104098183610d5b565b6006546104169190610d25565b6104209190610d3c565b945050505b5f831161045e5760405162461bcd60e51b815260206004820152600760248201526607a65726f206c760cc1b60448201526064016101d7565b80516003556020810151600455600680548491905f9061047f908490610d82565b9091555050335f90815260056020526040812080548592906104a2908490610d82565b9091555050604080518681526020810186905290810184905233907fbeb3885786d637a474cbc287c0a44587231633a077f0bd30354d5a4b18996fce9060600160405180910390a2505092915050565b5f82840361052f5760405162461bcd60e51b815260206004820152600a60248201526939b0b6b2903a37b5b2b760b11b60448201526064016101d7565b60028410801561053f5750600283105b6105775760405162461bcd60e51b81526020600482015260096024820152680c4c2c840d2dcc8caf60bb1b60448201526064016101d7565b5f82116105b05760405162461bcd60e51b81526020600482015260076024820152660f4cae4de40c8f60cb1b60448201526064016101d7565b5f84156105c8576001546001600160a01b03166105d4565b5f546001600160a01b03165b90505f84156105ee576001546001600160a01b03166105fa565b5f546001600160a01b03165b9050610608823330876108aa565b610610610c66565b600354815260045460208201526002545f9061062d9083906109bd565b90508582896002811061064257610642610d6e565b602002018181516106539190610d82565b9052505f61067c898985826002811061066e5761066e610d6e565b602002015185600254610b1a565b90505f83896002811061069157610691610d6e565b6020020151905060016106a48383610d5b565b6106ae9190610d5b565b96505f6127106106bf60048a610d25565b6106c99190610d3c565b90506106d58189610d5b565b97508a5f03610712578860035f8282546106ef9190610d82565b925050819055508760045f8282546107079190610d5b565b909155506107419050565b8860045f8282546107239190610d82565b925050819055508760035f82825461073b9190610d5b565b90915550505b61074c86338a6107a4565b604080518c8152602081018c90529081018a90526060810189905233907f49926bbebe8474393f434dfa4f78694c0923efa07d19f2284518bfabd06eb7379060800160405180910390a2505050505050509392505050565b6040516001600160a01b038381166024830152604482018390525f91829186169060640160408051601f198184030181529181526020820180516001600160e01b031663a9059cbb60e01b179052516107fd9190610d95565b5f604051808303815f865af19150503d805f8114610836576040519150601f19603f3d011682016040523d82523d5f602084013e61083b565b606091505b50915091508180156108655750805115806108655750808060200190518101906108659190610dab565b6108a35760405162461bcd60e51b815260206004820152600f60248201526e1d1c985b9cd9995c8819985a5b1959608a1b60448201526064016101d7565b5050505050565b6040516001600160a01b0384811660248301528381166044830152606482018390525f91829187169060840160408051601f198184030181529181526020820180516001600160e01b03166323b872dd60e01b1790525161090b9190610d95565b5f604051808303815f865af19150503d805f8114610944576040519150601f19603f3d011682016040523d82523d5f602084013e610949565b606091505b50915091508180156109735750805115806109735750808060200190518101906109739190610dab565b6109b55760405162461bcd60e51b81526020600482015260136024820152721d1c985b9cd9995c919c9bdb4819985a5b1959606a1b60448201526064016101d7565b505050505050565b602082015182515f9182916109d29190610d82565b9050805f036109e4575f915050610b14565b5f60026109f18186610d25565b6109fb9190610d25565b9050815f805b60ff811015610b0c5787518390610a1a90600290610d25565b610a248583610d25565b610a2e9190610d3c565b60208a0151909150610a4290600290610d25565b610a4c8583610d25565b610a569190610d3c565b849350905080610a6860026001610d82565b610a729190610d25565b84610a7e600188610d5b565b610a889190610d25565b610a929190610d82565b84610a9e600284610d25565b610aa88989610d25565b610ab29190610d82565b610abc9190610d25565b610ac69190610d3c565b935082841115610aec576001610adc8486610d5b565b11610ae75750610b0c565b610b03565b6001610af88585610d5b565b11610b035750610b0c565b50600101610a01565b509093505050505b92915050565b5f848603610b575760405162461bcd60e51b815260206004820152600a6024820152690e6c2daca40d2dcc8caf60b31b60448201526064016101d7565b5f6002610b648185610d25565b610b6e9190610d25565b905083610b7c600287610d25565b610b868683610d25565b610b909190610d3c565b9050610b9d600283610d25565b610ba78683610d25565b610bb19190610d3c565b90505f610bbe8387610d3c565b610bc89088610d82565b9050855f805b60ff811015610c56578291508884610be7846002610d25565b610bf19190610d82565b610bfb9190610d5b565b85610c068580610d25565b610c109190610d82565b610c1a9190610d3c565b925081831115610c3b576001610c308385610d5b565b1115610c5657610c4e565b6001610c478484610d5b565b1115610c56575b600101610bce565b50909a9950505050505050505050565b60405180604001604052806002906020820280368337509192915050565b5f60208284031215610c94575f80fd5b81356001600160a01b0381168114610caa575f80fd5b9392505050565b5f60208284031215610cc1575f80fd5b5035919050565b5f8060408385031215610cd9575f80fd5b50508035926020909101359150565b5f805f60608486031215610cfa575f80fd5b505081359360208301359350604090920135919050565b634e487b7160e01b5f52601160045260245ffd5b8082028115828204841417610b1457610b14610d11565b5f82610d5657634e487b7160e01b5f52601260045260245ffd5b500490565b81810381811115610b1457610b14610d11565b634e487b7160e01b5f52603260045260245ffd5b80820180821115610b1457610b14610d11565b5f82518060208501845e5f920191825250919050565b5f60208284031215610dbb575f80fd5b81518015158114610caa575f80fdfea264697066735822122013a1d05d8a5a1ad1a95e64d1d6a29e06ef387a84c8b64f47b5a2073429cf186e64736f6c634300081a0033" + + +### Setup contracts ############################################################# + +## Admin approves StableSwap to spend TokenA + +[[setup]] +kind = "admin_approve_stableswap_tokenA" +to = "{TokenA}" +signature = "approve(address spender, uint256 amount) returns (bool)" +args = [ + "{StableSwap}", + "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", +] + +## Admin approves StableSwap to spend TokenB + +[[setup]] +kind = "admin_approve_stableswap_tokenB" +to = "{TokenB}" +signature = "approve(address spender, uint256 amount) returns (bool)" +args = [ + "{StableSwap}", + "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", +] + +## Admin adds large initial liquidity (equal amounts — stablecoin pool) + +[[setup]] +kind = "admin_add_initial_liquidity" +to = "{StableSwap}" +signature = "addLiquidity(uint256 amountA, uint256 amountB) returns (uint256 lpAmount)" +args = ["{liquidityAmount}", "{liquidityAmount}"] +gas_limit = 500000 + +## Mint TokenA to all spammer accounts + +[[setup]] +kind = "mint_tokenA_for_spammer" +to = "{TokenA}" +from_pool = "spammer" +for_all_accounts = true +signature = "mint(address to, uint256 amount)" +args = ["{_sender}", "{spammerFunds}"] + +## Mint TokenB to all spammer accounts + +[[setup]] +kind = "mint_tokenB_for_spammer" +to = "{TokenB}" +from_pool = "spammer" +for_all_accounts = true +signature = "mint(address to, uint256 amount)" +args = ["{_sender}", "{spammerFunds}"] + +## All spammers approve StableSwap for TokenA + +[[setup]] +kind = "spammer_approve_stableswap_tokenA" +to = "{TokenA}" +from_pool = "spammer" +for_all_accounts = true +signature = "approve(address spender, uint256 amount) returns (bool)" +args = [ + "{StableSwap}", + "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", +] + +## All spammers approve StableSwap for TokenB + +[[setup]] +kind = "spammer_approve_stableswap_tokenB" +to = "{TokenB}" +from_pool = "spammer" +for_all_accounts = true +signature = "approve(address spender, uint256 amount) returns (bool)" +args = [ + "{StableSwap}", + "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", +] + + +### Spam patterns ############################################################## + +# Swap TokenA for TokenB (index 0 -> 1) +# Newton's method in getD + getY makes this ~2-3x more gas than constant-product +# Fuzz dx from 0.01 to 10 tokens (1e16 to 1e19 wei) +[[spam]] +[spam.tx] +kind = "stableswap_swap_0_to_1" +to = "{StableSwap}" +from_pool = "spammer" +signature = "swap(uint256 i, uint256 j, uint256 dx) returns (uint256 dy)" +args = ["0", "1", "10000000000000000"] +fuzz = [{ param = "dx", min = "10000000000000000", max = "10000000000000000000" }] + +# Swap TokenB for TokenA (index 1 -> 0) +# Fuzz dx from 0.01 to 10 tokens (1e16 to 1e19 wei) +[[spam]] +[spam.tx] +kind = "stableswap_swap_1_to_0" +to = "{StableSwap}" +from_pool = "spammer" +signature = "swap(uint256 i, uint256 j, uint256 dx) returns (uint256 dy)" +args = ["1", "0", "10000000000000000"] +fuzz = [{ param = "dx", min = "10000000000000000", max = "10000000000000000000" }] + +# Add liquidity with fuzzed amounts +# Fuzz both amounts from 0.01 to 1 token (1e16 to 1e18 wei) +[[spam]] +[spam.tx] +kind = "stableswap_add_liquidity" +to = "{StableSwap}" +from_pool = "spammer" +signature = "addLiquidity(uint256 amountA, uint256 amountB) returns (uint256 lpAmount)" +args = ["10000000000000000", "10000000000000000"] +fuzz = [ + { param = "amountA", min = "10000000000000000", max = "1000000000000000000" }, + { param = "amountB", min = "10000000000000000", max = "1000000000000000000" }, +] diff --git a/scenarios/stablecoin.toml b/scenarios/stablecoin.toml new file mode 100644 index 00000000..5fd392b3 --- /dev/null +++ b/scenarios/stablecoin.toml @@ -0,0 +1,70 @@ +# SimpleStablecoin scenario: ERC20 stablecoin with mint/burn mechanics +# Tests mint (payable), burn, transfer, and flashMintBurn patterns + +[[create]] +name = "SimpleStablecoin" +bytecode = "0x6080604052348015600e575f80fd5b50610c938061001c5f395ff3fe6080604052600436106100bf575f3560e01c806342966c681161007c57806395d89b411161005757806395d89b4114610213578063a9059cbb14610242578063dd62ed3e14610261578063f2f4567614610297575f80fd5b806342966c68146101b4578063664e9704146101d357806370a08231146101e8575f80fd5b806306fdde03146100c3578063095ea7b3146101145780631249c58b1461014357806318160ddd1461014d57806323b872dd1461016f578063313ce5671461018e575f80fd5b5f80fd5b3480156100ce575f80fd5b506100fe6040518060400160405280601081526020016f29b4b6b83632a9ba30b13632b1b7b4b760811b81525081565b60405161010b9190610a85565b60405180910390f35b34801561011f575f80fd5b5061013361012e366004610ad5565b6102b6565b604051901515815260200161010b565b61014b610322565b005b348015610158575f80fd5b506101615f5481565b60405190815260200161010b565b34801561017a575f80fd5b50610133610189366004610afd565b610415565b348015610199575f80fd5b506101a2601281565b60405160ff909116815260200161010b565b3480156101bf575f80fd5b5061014b6101ce366004610b37565b6105de565b3480156101de575f80fd5b506101616103e881565b3480156101f3575f80fd5b50610161610202366004610b4e565b60016020525f908152604090205481565b34801561021e575f80fd5b506100fe6040518060400160405280600481526020016314d554d160e21b81525081565b34801561024d575f80fd5b5061013361025c366004610ad5565b61081a565b34801561026c575f80fd5b5061016161027b366004610b6e565b600260209081525f928352604080842090915290825290205481565b3480156102a2575f80fd5b5061014b6102b1366004610b37565b610913565b335f8181526002602090815260408083206001600160a01b038716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925906103109086815260200190565b60405180910390a35060015b92915050565b5f34116103665760405162461bcd60e51b815260206004820152600d60248201526c09aeae6e840e6cadcc8408aa89609b1b60448201526064015b60405180910390fd5b5f6103736103e834610bb3565b335f90815260016020526040812080549293508392909190610396908490610bca565b92505081905550805f808282546103ad9190610bca565b909155505060405181815233905f905f80516020610c3e8339815191529060200160405180910390a3604080513481526020810183905233917f4c209b5fc8ad50758f13e2e1088ba56a560dff690a1c6fef26394f4c03821c4f91015b60405180910390a250565b5f6001600160a01b0383166104675760405162461bcd60e51b81526020600482015260186024820152775472616e7366657220746f207a65726f206164647265737360401b604482015260640161035d565b6001600160a01b0384165f9081526001602052604090205482111561049e5760405162461bcd60e51b815260040161035d90610bdd565b6001600160a01b0384165f9081526002602090815260408083203384529091529020548211156105095760405162461bcd60e51b8152602060048201526016602482015275496e73756666696369656e7420616c6c6f77616e636560501b604482015260640161035d565b6001600160a01b0384165f9081526002602090815260408083203384529091528120805484929061053b908490610c0b565b90915550506001600160a01b0384165f9081526001602052604081208054849290610567908490610c0b565b90915550506001600160a01b0383165f9081526001602052604081208054849290610593908490610bca565b92505081905550826001600160a01b0316846001600160a01b03165f80516020610c3e833981519152846040516105cc91815260200190565b60405180910390a35060019392505050565b5f81116106225760405162461bcd60e51b81526020600482015260126024820152710416d6f756e74206d757374206265203e20360741b604482015260640161035d565b335f908152600160205260409020548111156106505760405162461bcd60e51b815260040161035d90610bdd565b5f61065d6103e883610c1e565b90505f81116106a15760405162461bcd60e51b815260206004820152601060248201526f105b5bdd5b9d081d1bdbc81cdb585b1b60821b604482015260640161035d565b804710156106f15760405162461bcd60e51b815260206004820152601960248201527f496e73756666696369656e7420636f6e74726163742045544800000000000000604482015260640161035d565b335f908152600160205260408120805484929061070f908490610c0b565b92505081905550815f808282546107269190610c0b565b90915550506040518281525f9033905f80516020610c3e8339815191529060200160405180910390a3604080518381526020810183905233917f49995e5dd6158cf69ad3e9777c46755a1a826a446c6416992167462dad033b2a910160405180910390a26040515f90339083908381818185875af1925050503d805f81146107c9576040519150601f19603f3d011682016040523d82523d5f602084013e6107ce565b606091505b50509050806108155760405162461bcd60e51b8152602060048201526013602482015272115512081d1c985b9cd9995c8819985a5b1959606a1b604482015260640161035d565b505050565b5f6001600160a01b03831661086c5760405162461bcd60e51b81526020600482015260186024820152775472616e7366657220746f207a65726f206164647265737360401b604482015260640161035d565b335f9081526001602052604090205482111561089a5760405162461bcd60e51b815260040161035d90610bdd565b335f90815260016020526040812080548492906108b8908490610c0b565b90915550506001600160a01b0383165f90815260016020526040812080548492906108e4908490610bca565b90915550506040518281526001600160a01b0384169033905f80516020610c3e83398151915290602001610310565b5f81116109575760405162461bcd60e51b81526020600482015260126024820152710416d6f756e74206d757374206265203e20360741b604482015260640161035d565b335f9081526001602052604081208054839290610975908490610bca565b92505081905550805f8082825461098c9190610bca565b909155505060405181815233905f905f80516020610c3e8339815191529060200160405180910390a3604080515f81526020810183905233917f4c209b5fc8ad50758f13e2e1088ba56a560dff690a1c6fef26394f4c03821c4f910160405180910390a2335f9081526001602052604081208054839290610a0e908490610c0b565b92505081905550805f80828254610a259190610c0b565b90915550506040518181525f9033905f80516020610c3e8339815191529060200160405180910390a3604080518281525f602082015233917f49995e5dd6158cf69ad3e9777c46755a1a826a446c6416992167462dad033b2a910161040a565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f83011684010191505092915050565b80356001600160a01b0381168114610ad0575f80fd5b919050565b5f8060408385031215610ae6575f80fd5b610aef83610aba565b946020939093013593505050565b5f805f60608486031215610b0f575f80fd5b610b1884610aba565b9250610b2660208501610aba565b929592945050506040919091013590565b5f60208284031215610b47575f80fd5b5035919050565b5f60208284031215610b5e575f80fd5b610b6782610aba565b9392505050565b5f8060408385031215610b7f575f80fd5b610b8883610aba565b9150610b9660208401610aba565b90509250929050565b634e487b7160e01b5f52601160045260245ffd5b808202811582820484141761031c5761031c610b9f565b8082018082111561031c5761031c610b9f565b602080825260149082015273496e73756666696369656e742062616c616e636560601b604082015260600190565b8181038181111561031c5761031c610b9f565b5f82610c3857634e487b7160e01b5f52601260045260245ffd5b50049056feddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa2646970667358221220cf14a6da4d4c7492f77ff9da228f381c85f6016d6985a1a619d9627a8b754bd464736f6c634300081a0033" + + +# Setup: Admin mints stablecoins by sending 10 ETH (gets 10,000 tokens) +[[setup]] +kind = "admin_mint" +to = "{SimpleStablecoin}" +signature = "mint()" +args = [] +value = "10 eth" + +# Setup: Each spammer account mints stablecoins by sending 1 ETH (gets 1,000 tokens each) +[[setup]] +kind = "spammer_mint" +to = "{SimpleStablecoin}" +from_pool = "spammer" +for_all_accounts = true +signature = "mint()" +args = [] +value = "1 eth" + + +# Spam 1: Mint stablecoins (payable) - fuzz ETH value from 0.001 to 0.01 +[[spam]] +[spam.tx] +kind = "stablecoin_mint" +to = "{SimpleStablecoin}" +from_pool = "spammer" +signature = "mint()" +args = [] +value = "0.005 eth" +fuzz = [{ param = "value", min = "1000000000000000", max = "10000000000000000" }] + +# Spam 2: Burn stablecoins - fuzz amount from 1e15 to 1e16 +# gas_limit set to handle potential reverts (insufficient balance) +[[spam]] +[spam.tx] +kind = "stablecoin_burn" +to = "{SimpleStablecoin}" +from_pool = "spammer" +signature = "function burn(uint256 amount)" +args = ["5000000000000000"] +gas_limit = 100000 +fuzz = [{ param = "amount", min = "1000000000000000", max = "10000000000000000" }] + +# Spam 3: ERC20 transfer - fuzz amount, send to self ({_sender}) +[[spam]] +[spam.tx] +kind = "stablecoin_transfer" +to = "{SimpleStablecoin}" +from_pool = "spammer" +signature = "function transfer(address to, uint256 amount) returns (bool)" +args = ["{_sender}", "500000000000000000"] +fuzz = [{ param = "amount", min = "100000000000000000", max = "1000000000000000000" }] + +# Spam 4: Flash mint+burn - heavy storage ops, no ETH needed +# Fuzz amount from 1e18 to 1e21 (two balance updates, two supply updates, 4 events) +[[spam]] +[spam.tx] +kind = "stablecoin_flash_mint_burn" +to = "{SimpleStablecoin}" +from_pool = "spammer" +signature = "function flashMintBurn(uint256 amount)" +args = ["1000000000000000000000"] +fuzz = [{ param = "amount", min = "1000000000000000000", max = "1000000000000000000000" }] diff --git a/scenarios/staking.toml b/scenarios/staking.toml new file mode 100644 index 00000000..00fe9aef --- /dev/null +++ b/scenarios/staking.toml @@ -0,0 +1,108 @@ +# ============================================================ +# Token Staking & Rewards - Stress Test +# ============================================================ +# Source: /tmp/staking.sol (StakingToken + SimpleStaking) +# Gas profile: multiple storage updates, token transfers, +# reward calculation, mint calls per tx +# ============================================================ + +[env] +initialSupply = "1000000000000000000000000000" +spammerMintAmount = "1000000000000000000000000" +spammerStakeAmount = "500000000000000000000000" +rewardPoolAmount = "100000000000000000000000000" + +### Deploy contracts + +[[create]] +name = "StakingToken" +signature = "(uint256 initialSupply)" +args = ["{initialSupply}"] +bytecode = "0x60c0604052600c60809081526b29ba30b5b4b733aa37b5b2b760a11b60a0525f9061002a9082610170565b5060408051808201909152600381526253544b60e81b60208201526001906100529082610170565b506002805460ff1916601217905534801561006b575f80fd5b506040516109bc3803806109bc83398101604081905261008a9161022a565b6003819055335f818152600460209081526040808320859055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a350610241565b634e487b7160e01b5f52604160045260245ffd5b600181811c9082168061010057607f821691505b60208210810361011e57634e487b7160e01b5f52602260045260245ffd5b50919050565b601f82111561016b57805f5260205f20601f840160051c810160208510156101495750805b601f840160051c820191505b81811015610168575f8155600101610155565b50505b505050565b81516001600160401b03811115610189576101896100d8565b61019d8161019784546100ec565b84610124565b6020601f8211600181146101cf575f83156101b85750848201515b5f19600385901b1c1916600184901b178455610168565b5f84815260208120601f198516915b828110156101fe57878501518255602094850194600190920191016101de565b508482101561021b57868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b5f6020828403121561023a575f80fd5b5051919050565b61076e8061024e5f395ff3fe608060405234801561000f575f80fd5b506004361061009b575f3560e01c806340c10f191161006357806340c10f191461012957806370a082311461013e57806395d89b411461015d578063a9059cbb14610165578063dd62ed3e14610178575f80fd5b806306fdde031461009f578063095ea7b3146100bd57806318160ddd146100e057806323b872dd146100f7578063313ce5671461010a575b5f80fd5b6100a76101a2565b6040516100b491906105c3565b60405180910390f35b6100d06100cb366004610613565b61022d565b60405190151581526020016100b4565b6100e960035481565b6040519081526020016100b4565b6100d061010536600461063b565b610299565b6002546101179060ff1681565b60405160ff90911681526020016100b4565b61013c610137366004610613565b61044f565b005b6100e961014c366004610675565b60046020525f908152604090205481565b6100a76104d5565b6100d0610173366004610613565b6104e2565b6100e9610186366004610695565b600560209081525f928352604080842090915290825290205481565b5f80546101ae906106c6565b80601f01602080910402602001604051908101604052809291908181526020018280546101da906106c6565b80156102255780601f106101fc57610100808354040283529160200191610225565b820191905f5260205f20905b81548152906001019060200180831161020857829003601f168201915b505050505081565b335f8181526005602090815260408083206001600160a01b038716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925906102879086815260200190565b60405180910390a35060015b92915050565b6001600160a01b0383165f908152600460205260408120548211156102fc5760405162461bcd60e51b8152602060048201526014602482015273696e73756666696369656e742062616c616e636560601b60448201526064015b60405180910390fd5b6001600160a01b0384165f9081526005602090815260408083203384529091529020548211156103675760405162461bcd60e51b8152602060048201526016602482015275696e73756666696369656e7420616c6c6f77616e636560501b60448201526064016102f3565b6001600160a01b0384165f90815260056020908152604080832033845290915281208054849290610399908490610712565b90915550506001600160a01b0384165f90815260046020526040812080548492906103c5908490610712565b90915550506001600160a01b0383165f90815260046020526040812080548492906103f1908490610725565b92505081905550826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161043d91815260200190565b60405180910390a35060019392505050565b8060035f8282546104609190610725565b90915550506001600160a01b0382165f908152600460205260408120805483929061048c908490610725565b90915550506040518181526001600160a01b038316905f907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b600180546101ae906106c6565b335f908152600460205260408120548211156105375760405162461bcd60e51b8152602060048201526014602482015273696e73756666696369656e742062616c616e636560601b60448201526064016102f3565b335f9081526004602052604081208054849290610555908490610712565b90915550506001600160a01b0383165f9081526004602052604081208054849290610581908490610725565b90915550506040518281526001600160a01b0384169033907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602001610287565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f83011684010191505092915050565b80356001600160a01b038116811461060e575f80fd5b919050565b5f8060408385031215610624575f80fd5b61062d836105f8565b946020939093013593505050565b5f805f6060848603121561064d575f80fd5b610656846105f8565b9250610664602085016105f8565b929592945050506040919091013590565b5f60208284031215610685575f80fd5b61068e826105f8565b9392505050565b5f80604083850312156106a6575f80fd5b6106af836105f8565b91506106bd602084016105f8565b90509250929050565b600181811c908216806106da57607f821691505b6020821081036106f857634e487b7160e01b5f52602260045260245ffd5b50919050565b634e487b7160e01b5f52601160045260245ffd5b81810381811115610293576102936106fe565b80820180821115610293576102936106fe56fea264697066735822122093854287f1afdd7c0297708d0041ece6c38028f0f61f438279f24438b574318964736f6c634300081a0033" + +[[create]] +name = "SimpleStaking" +signature = "(address stakingToken_)" +args = ["{StakingToken}"] +bytecode = "0x6080604052348015600e575f80fd5b50604051610759380380610759833981016040819052602b91604e565b5f80546001600160a01b0319166001600160a01b03929092169190911790556079565b5f60208284031215605d575f80fd5b81516001600160a01b03811681146072575f80fd5b9392505050565b6106d3806100865f395ff3fe608060405234801561000f575f80fd5b506004361061007a575f3560e01c806372f702f31161005857806372f702f3146100cd578063817b1cd2146100f7578063a694fc3a14610100578063f69e204614610113575f80fd5b80632e17de781461007e578063372500ab14610093578063602172671461009b575b5f80fd5b61009161008c3660046105e1565b61011b565b005b6100916102a6565b6100ba6100a93660046105f8565b60016020525f908152604090205481565b6040519081526020015b60405180910390f35b5f546100df906001600160a01b031681565b6040516001600160a01b0390911681526020016100c4565b6100ba60025481565b61009161010e3660046105e1565b61037e565b6100916104a3565b5f81116101625760405162461bcd60e51b815260206004820152601060248201526f063616e6e6f7420756e7374616b6520360841b60448201526064015b60405180910390fd5b335f908152600160205260409020548111156101c05760405162461bcd60e51b815260206004820152601b60248201527f696e73756666696369656e74207374616b65642062616c616e636500000000006044820152606401610159565b335f90815260016020526040812080548392906101de908490610639565b925050819055508060025f8282546101f69190610639565b90915550505f5460405163a9059cbb60e01b8152336004820152602481018390526001600160a01b039091169063a9059cbb906044016020604051808303815f875af1158015610248573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061026c919061064c565b5060405181815233907f0f5bb82176feb1b5e747e28471aa92156a04d9f3ab9f45f28e2d704232b93f75906020015b60405180910390a250565b5f6102b0336105b7565b90505f81116102ee5760405162461bcd60e51b815260206004820152600a6024820152696e6f207265776172647360b01b6044820152606401610159565b5f546040516340c10f1960e01b8152336004820152602481018390526001600160a01b03909116906340c10f19906044015f604051808303815f87803b158015610336575f80fd5b505af1158015610348573d5f803e3d5ffd5b50506040518381523392507f106f923f993c2149d49b4255ff723acafa1f2d94393f561d3eda32ae348f7241915060200161029b565b5f81116103be5760405162461bcd60e51b815260206004820152600e60248201526d063616e6e6f74207374616b6520360941b6044820152606401610159565b5f546040516323b872dd60e01b8152336004820152306024820152604481018390526001600160a01b03909116906323b872dd906064016020604051808303815f875af1158015610411573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610435919061064c565b50335f908152600160205260408120805483929061045490849061066b565b925050819055508060025f82825461046c919061066b565b909155505060405181815233907f9e71bc8eea02a63969f509818f2dafb9254532904319f9dbda79b67bd34a5f3d9060200161029b565b5f6104ad336105b7565b90505f81116104eb5760405162461bcd60e51b815260206004820152600a6024820152696e6f207265776172647360b01b6044820152606401610159565b5f546040516340c10f1960e01b8152306004820152602481018390526001600160a01b03909116906340c10f19906044015f604051808303815f87803b158015610533575f80fd5b505af1158015610545573d5f803e3d5ffd5b5050335f908152600160205260408120805485945090925061056890849061066b565b925050819055508060025f828254610580919061066b565b909155505060405181815233907fc16de066392da7e40ceccb739c331fc48a2e76bf147449613c48023d960eec329060200161029b565b6001600160a01b0381165f908152600160205260408120546105db9060649061067e565b92915050565b5f602082840312156105f1575f80fd5b5035919050565b5f60208284031215610608575f80fd5b81356001600160a01b038116811461061e575f80fd5b9392505050565b634e487b7160e01b5f52601160045260245ffd5b818103818111156105db576105db610625565b5f6020828403121561065c575f80fd5b8151801515811461061e575f80fd5b808201808211156105db576105db610625565b5f8261069857634e487b7160e01b5f52601260045260245ffd5b50049056fea26469706673582212205b4355347c8ba0342b6a882e0e7548a73d1d78123b70023ba2fb831802366a7e64736f6c634300081a0033" + +### Setup: fund the staking contract with reward tokens + +[[setup]] +kind = "admin_mint_rewards" +to = "{StakingToken}" +signature = "mint(address to, uint256 amount)" +args = ["{SimpleStaking}", "{rewardPoolAmount}"] + +### Setup: mint tokens to all spammer accounts + +[[setup]] +kind = "spammer_mint_tokens" +to = "{StakingToken}" +from_pool = "spammer" +for_all_accounts = true +signature = "mint(address to, uint256 amount)" +args = ["{_sender}", "{spammerMintAmount}"] + +### Setup: each spammer approves the staking contract + +[[setup]] +kind = "spammer_approve_staking" +to = "{StakingToken}" +from_pool = "spammer" +for_all_accounts = true +signature = "approve(address spender, uint256 amount) returns (bool)" +args = ["{SimpleStaking}", "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"] + +### Setup: each spammer stakes an initial amount + +[[setup]] +kind = "spammer_initial_stake" +to = "{SimpleStaking}" +from_pool = "spammer" +for_all_accounts = true +signature = "stake(uint256 amount)" +args = ["{spammerStakeAmount}"] + +### Spam patterns + +# 1. Stake additional tokens (fuzz amount) +[[spam]] +[spam.tx] +kind = "stake" +to = "{SimpleStaking}" +from_pool = "spammer" +signature = "stake(uint256 amount)" +args = ["50000000000000000"] +fuzz = [{ param = "amount", min = "1000000000000000", max = "100000000000000000" }] + +# 2. Unstake tokens (fuzz amount, with gas_limit) +[[spam]] +[spam.tx] +kind = "unstake" +to = "{SimpleStaking}" +from_pool = "spammer" +signature = "unstake(uint256 amount)" +args = ["5000000000000000"] +gas_limit = 200000 +fuzz = [{ param = "amount", min = "100000000000000", max = "10000000000000000" }] + +# 3. Claim rewards (gas_limit set) +[[spam]] +[spam.tx] +kind = "claim_rewards" +to = "{SimpleStaking}" +from_pool = "spammer" +signature = "claimRewards()" +args = [] +gas_limit = 200000 + +# 4. Compound rewards (gas_limit set) +[[spam]] +[spam.tx] +kind = "compound" +to = "{SimpleStaking}" +from_pool = "spammer" +signature = "compound()" +args = [] +gas_limit = 200000 diff --git a/scenarios/weth.toml b/scenarios/weth.toml new file mode 100644 index 00000000..f44e61bf --- /dev/null +++ b/scenarios/weth.toml @@ -0,0 +1,84 @@ +# ============================================================ +# WETH9 Wrap/Unwrap - Stress Test +# ============================================================ +# Source: /tmp/weth.sol (WETH9) +# WETH is the highest-volume contract on Ethereum mainnet. +# Covers payable + msg.value pattern, basic ERC20 operations. +# ============================================================ + +[env] +adminDepositAmount = "100000000000000000000" +spammerDepositAmount = "1000000000000000000" + +### Deploy WETH9 + +[[create]] +name = "WETH9" +bytecode = "0x60c0604052600d60809081526c2bb930b83832b21022ba3432b960991b60a0525f9061002b908261010b565b506040805180820190915260048152630ae8aa8960e31b6020820152600190610054908261010b565b506002805460ff1916601217905534801561006d575f80fd5b506101c5565b634e487b7160e01b5f52604160045260245ffd5b600181811c9082168061009b57607f821691505b6020821081036100b957634e487b7160e01b5f52602260045260245ffd5b50919050565b601f82111561010657805f5260205f20601f840160051c810160208510156100e45750805b601f840160051c820191505b81811015610103575f81556001016100f0565b50505b505050565b81516001600160401b0381111561012457610124610073565b610138816101328454610087565b846100bf565b6020601f82116001811461016a575f83156101535750848201515b5f19600385901b1c1916600184901b178455610103565b5f84815260208120601f198516915b828110156101995787850151825560209485019460019092019101610179565b50848210156101b657868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b61088a806101d25f395ff3fe60806040526004361061009d575f3560e01c8063313ce56711610062578063313ce5671461016357806370a082311461018e57806395d89b41146101b9578063a9059cbb146101cd578063d0e30db0146101ec578063dd62ed3e146101f4575f80fd5b806306fdde03146100b0578063095ea7b3146100da57806318160ddd1461010957806323b872dd146101255780632e1a7d4d14610144575f80fd5b366100ac576100aa61022a565b005b5f80fd5b3480156100bb575f80fd5b506100c4610284565b6040516100d191906106cf565b60405180910390f35b3480156100e5575f80fd5b506100f96100f436600461071f565b61030f565b60405190151581526020016100d1565b348015610114575f80fd5b50475b6040519081526020016100d1565b348015610130575f80fd5b506100f961013f366004610747565b61037b565b34801561014f575f80fd5b506100aa61015e366004610781565b610573565b34801561016e575f80fd5b5060025461017c9060ff1681565b60405160ff90911681526020016100d1565b348015610199575f80fd5b506101176101a8366004610798565b60036020525f908152604090205481565b3480156101c4575f80fd5b506100c46106af565b3480156101d8575f80fd5b506100f96101e736600461071f565b6106bc565b6100aa61022a565b3480156101ff575f80fd5b5061011761020e3660046107b1565b600460209081525f928352604080842090915290825290205481565b335f90815260036020526040812080543492906102489084906107f6565b909155505060405134815233907fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c9060200160405180910390a2565b5f805461029090610809565b80601f01602080910402602001604051908101604052809291908181526020018280546102bc90610809565b80156103075780601f106102de57610100808354040283529160200191610307565b820191905f5260205f20905b8154815290600101906020018083116102ea57829003601f168201915b505050505081565b335f8181526004602090815260408083206001600160a01b038716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925906103699086815260200190565b60405180910390a35060015b92915050565b6001600160a01b0383165f908152600360205260408120548211156103de5760405162461bcd60e51b8152602060048201526014602482015273696e73756666696369656e742062616c616e636560601b60448201526064015b60405180910390fd5b6001600160a01b038416331480159061041a57506001600160a01b0384165f9081526004602090815260408083203384529091529020545f1914155b156104c2576001600160a01b0384165f90815260046020908152604080832033845290915290205482111561048a5760405162461bcd60e51b8152602060048201526016602482015275696e73756666696369656e7420616c6c6f77616e636560501b60448201526064016103d5565b6001600160a01b0384165f908152600460209081526040808320338452909152812080548492906104bc908490610841565b90915550505b6001600160a01b0384165f90815260036020526040812080548492906104e9908490610841565b90915550506001600160a01b0383165f90815260036020526040812080548492906105159084906107f6565b92505081905550826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161056191815260200190565b60405180910390a35060019392505050565b335f908152600360205260409020548111156105c85760405162461bcd60e51b8152602060048201526014602482015273696e73756666696369656e742062616c616e636560601b60448201526064016103d5565b335f90815260036020526040812080548392906105e6908490610841565b90915550506040515f90339083908381818185875af1925050503d805f811461062a576040519150601f19603f3d011682016040523d82523d5f602084013e61062f565b606091505b50509050806106765760405162461bcd60e51b8152602060048201526013602482015272115512081d1c985b9cd9995c8819985a5b1959606a1b60448201526064016103d5565b60405182815233907f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b659060200160405180910390a25050565b6001805461029090610809565b5f6106c833848461037b565b9392505050565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f83011684010191505092915050565b80356001600160a01b038116811461071a575f80fd5b919050565b5f8060408385031215610730575f80fd5b61073983610704565b946020939093013593505050565b5f805f60608486031215610759575f80fd5b61076284610704565b925061077060208501610704565b929592945050506040919091013590565b5f60208284031215610791575f80fd5b5035919050565b5f602082840312156107a8575f80fd5b6106c882610704565b5f80604083850312156107c2575f80fd5b6107cb83610704565b91506107d960208401610704565b90509250929050565b634e487b7160e01b5f52601160045260245ffd5b80820180821115610375576103756107e2565b600181811c9082168061081d57607f821691505b60208210810361083b57634e487b7160e01b5f52602260045260245ffd5b50919050565b81810381811115610375576103756107e256fea26469706673582212209f4c63a6c1d2e5d7c4951f4a4c97a4f93b18d576f85f9600f6fc0b7ec7e960fd64736f6c634300081a0033" + +### Setup: Admin deposits 100 ETH into WETH + +[[setup]] +kind = "admin_deposit" +to = "{WETH9}" +signature = "deposit()" +args = [] +value = "100 eth" + +### Setup: Each spammer deposits 1 ETH into WETH + +[[setup]] +kind = "spammer_deposit" +to = "{WETH9}" +from_pool = "spammer" +for_all_accounts = true +signature = "deposit()" +args = [] +value = "1 eth" + +### Spam patterns + +# 1. Deposit (wrap ETH) — fuzz value from 0.001 to 0.01 ETH +[[spam]] +[spam.tx] +kind = "deposit" +to = "{WETH9}" +from_pool = "spammer" +signature = "deposit()" +args = [] +value = "0.005 eth" +fuzz = [ + { value = true, min = "1000000000000000", max = "10000000000000000" }, +] + +# 2. Withdraw (unwrap WETH) — fuzz wad from 1e14 to 1e16 +[[spam]] +[spam.tx] +kind = "withdraw" +to = "{WETH9}" +from_pool = "spammer" +signature = "withdraw(uint256 wad)" +args = ["5000000000000000"] +gas_limit = 200000 +fuzz = [{ param = "wad", min = "100000000000000", max = "10000000000000000" }] + +# 3. Transfer WETH — fuzz amount from 1e14 to 1e16 +[[spam]] +[spam.tx] +kind = "transfer" +to = "{WETH9}" +from_pool = "spammer" +signature = "transfer(address dst, uint256 wad) returns (bool)" +args = ["{_sender}", "5000000000000000"] +gas_limit = 200000 +fuzz = [{ param = "wad", min = "100000000000000", max = "10000000000000000" }] + +# 4. Approve — fuzz allowance amount +[[spam]] +[spam.tx] +kind = "approve" +to = "{WETH9}" +from_pool = "spammer" +signature = "approve(address guy, uint256 wad) returns (bool)" +args = ["{_sender}", "5000000000000000000"] +fuzz = [{ param = "wad", min = "1000000000000000000", max = "10000000000000000000" }]