Skip to content

Commit

Permalink
Add extra method self execute
Browse files Browse the repository at this point in the history
  • Loading branch information
Agusx1211 committed Jan 25, 2024
1 parent a698bf3 commit 8a319ae
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 9 deletions.
4 changes: 2 additions & 2 deletions foundry_test/modules/utils/L2CompressorHuffReadExecute.sol
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ import { HuffDeployer } from "foundry-huff/HuffDeployer.sol";

import "contracts/modules/commons/interfaces/IModuleCalls.sol";

uint256 constant FMS = 0xa0;

import "./L2CompressorEncoder.sol";

uint256 constant FMS = 0xa0;

contract L2CompressorHuffReadExecuteTest is AdvTest {
address public imp;

Expand Down
39 changes: 38 additions & 1 deletion foundry_test/modules/utils/L2CompressorHuffReadFlag.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import "forge-std/console2.sol";
import { HuffConfig } from "foundry-huff/HuffConfig.sol";
import { HuffDeployer } from "foundry-huff/HuffDeployer.sol";

import "contracts/modules/commons/interfaces/IModuleCalls.sol";

import "./L2CompressorEncoder.sol";

uint256 constant FMS = 0xa0;
Expand Down Expand Up @@ -999,7 +1001,7 @@ contract L2CompressorHuffReadFlagTests is AdvTest {
}

function test_read_pow_10_and_mul(uint256 _exp, uint8 _factor) external {
_exp = bound(_exp, 0, 77);
_exp = bound(_exp, 1, 77);

// First bit means we aren't going to multiply it after
bytes memory encoded = abi.encodePacked(uint8(0x00), uint8(_exp), uint8(_factor));
Expand All @@ -1015,4 +1017,39 @@ contract L2CompressorHuffReadFlagTests is AdvTest {
assertEq(res, abi.encode(uint256(10 ** _exp) * uint256(_factor)));
}
}

function test_read_self_execute() external {
// vm.assume(_txs.length != 0 && _txs.length <= type(uint8).max);

IModuleCalls.Transaction[] memory _txs = new IModuleCalls.Transaction[](1);

bytes memory encoded = abi.encodePacked(
uint8(0x00), uint8(0x00),
uint8(_txs.length)
);

for (uint256 i = 0; i < _txs.length; i++) {
IModuleCalls.Transaction memory t = _txs[i];

encoded = abi.encodePacked(
encoded,
build_flag(t.delegateCall, t.revertOnError, t.gasLimit != 0, t.value != 0, t.data.length != 0),
t.gasLimit != 0 ? encodeWord(t.gasLimit) : bytes(""),
encode_raw_address(t.target),
t.value != 0 ? encodeWord(t.value) : bytes(""),
t.data.length != 0 ? encode_bytes_n(t.data) : bytes("")
);
}

(bool s, bytes memory r) = imp.staticcall(encoded);

assertTrue(s);
(uint256 rindex, uint256 windex, bytes memory res) = abi.decode(r, (uint256, uint256, bytes));

assertEq(rindex, encoded.length);
assertEq(windex, res.length + FMS);

bytes memory solidityEncoded = abi.encodeWithSelector(IModuleCalls.selfExecute.selector, _txs);
assertEq(solidityEncoded, res);
}
}
56 changes: 50 additions & 6 deletions src/L2Compressor.huff
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@
}

#define jumptable__packed FLAG_TABLE {
FLAG_READ_POWER_OF_10 // 0x00
FLAG_READ_POWER_OF_10_MISC // 0x00
FLAG_READ_BYTES32_1_BYTES // 0x01
FLAG_READ_BYTES32_2_BYTES // 0x02
FLAG_READ_BYTES32_3_BYTES // 0x03
Expand Down Expand Up @@ -217,8 +217,8 @@
0xf0 shr // [word >> 0xf0, windex, rindex + 1, jump_to]
jump // [windex, rindex + 1, jump_to]

FLAG_READ_POWER_OF_10:
READ_POW_10()
FLAG_READ_POWER_OF_10_MISC:
READ_POW_10_AND_SELF_EXECUTE(<nrfs>)
end jump
FLAG_READ_BYTES32_1_BYTES:
READ_BYTES32(0xf8, 0x01)
Expand Down Expand Up @@ -490,12 +490,29 @@
// output stack: // [windex, rindex]
}

#define macro READ_POW_10() = takes (2) returns (2) {
#define macro READ_POW_10_AND_SELF_EXECUTE(nrfs) = takes (2) returns (2) {
// input stack: [windex, rindex]

swap1 // [rindex, windex]
LOAD_DYNAMIC_SIZE(0x01, 0xf8) // [exp_word, rindex, windex]

// We didn't had any more pleace for READ_SELF_EXECUTE without expanding
// the jumptable! so it has to live here. Sorry about that.
// 10 ** 0 * N is more expensive than just reading 1 byte,
// so this wasn't useful anyway

dup1 // [exp_word, exp_word, rindex, windex]
normal_flow jumpi // [exp_word, rindex, windex]

// --- WARNING UGLY CODE ---

pop // [rindex, windex]
swap1 // [windex, rindex]
READ_SELF_EXECUTE(<nrfs>) // [windex, rindex]
end_pow_10 jump // [windex, rindex]

normal_flow:

// The last bit determines if we will multiply this by
// the next byte or not, this is fine as the maximum value that we
// can represent in a word is only 10 ** 78
Expand All @@ -512,7 +529,8 @@
swap1 // [rindex, windex, not_use_mul]
swap2 // [not_use_mul, windex, rindex]

no_mul jumpi // [windex, rindex]
end_pow_10 jumpi // [windex, rindex]

BACKREAD_SINGLE_VALUE() // [pow_result, windex, rindex]
swap2 // [rindex, windex, pow_result]
LOAD_DYNAMIC_SIZE(0x01, 0xf8) // [factor, rindex, windex, pow_result]
Expand All @@ -524,7 +542,7 @@
0x20 // [0x20, windex, rindex]
add // [(0x20 + windex), rindex]

no_mul: // [windex, rindex]
end_pow_10: // [windex, rindex]

// output stack: [windex, rindex]
}
Expand Down Expand Up @@ -1606,6 +1624,32 @@
end_data_if:
}

#define macro READ_SELF_EXECUTE(nrfs) = takes (2) returns (2) {
// input stack: [windex, rindex]

// The SELF execution function signature of Sequence is 0x61c2926c

__RIGHTPAD(0x61c2926c) // [0x61c2926c, windex, rindex]
dup2 // [windex, 0x61c2926c, windex, rindex]
mstore // [windex, rindex]
0x04 add // [windex, rindex]

// We need to write a single 0x20, this marks the position
// of the list of transactions. It is always the same.
0x20 // [0x20, windex, rindex]
dup1 // [0x20, 0x20, windex, rindex]
dup3 // [windex, 0x20, 0x20, windex, rindex]
mstore // [0x20, windex, rindex]
add // [(0x20 + windex), rindex]

// Now we can just read the list of transactions
// the macro handles all internal pointers

READ_TRANSACTIONS(<nrfs>) // [windex, rindex]

// output stack: [windex, rindex]
}

#define macro READ_ABI_4_BYTES() = takes (2) returns (2) {
// input stack: [windex, rindex]

Expand Down

0 comments on commit 8a319ae

Please sign in to comment.