Skip to content

Commit dcd5ade

Browse files
committed
Implement ERC-7821 calldata compression in ERC7579Utils
1 parent 39f5a02 commit dcd5ade

File tree

2 files changed

+39
-2
lines changed

2 files changed

+39
-2
lines changed

contracts/account/utils/draft-ERC7579Utils.sol

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,9 @@ library ERC7579Utils {
218218
uint256 value,
219219
bytes calldata data
220220
) private returns (bytes memory) {
221-
(bool success, bytes memory returndata) = target.call{value: value}(data);
221+
(bool success, bytes memory returndata) = (target == address(0) ? address(this) : target).call{value: value}(
222+
data
223+
);
222224
return _validateExecutionMode(index, execType, success, returndata);
223225
}
224226

@@ -229,7 +231,7 @@ library ERC7579Utils {
229231
address target,
230232
bytes calldata data
231233
) private returns (bytes memory) {
232-
(bool success, bytes memory returndata) = target.delegatecall(data);
234+
(bool success, bytes memory returndata) = (target == address(0) ? address(this) : target).delegatecall(data);
233235
return _validateExecutionMode(index, execType, success, returndata);
234236
}
235237

test/account/utils/draft-ERC7579Utils.test.js

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ const {
99
encodeDelegate,
1010
CALL_TYPE_CALL,
1111
CALL_TYPE_BATCH,
12+
CALL_TYPE_DELEGATE,
1213
encodeMode,
1314
} = require('../../helpers/erc7579');
1415
const { selector } = require('../../helpers/methods');
@@ -54,6 +55,18 @@ describe('ERC7579Utils', function () {
5455
await expect(ethers.provider.getBalance(this.target)).to.eventually.equal(value);
5556
});
5657

58+
it('default to calling self is target is address(0) (ERC-7821 calldata compression)', async function () {
59+
const data = encodeSingle(
60+
ethers.ZeroAddress, // address(0)
61+
0,
62+
this.utils.interface.encodeFunctionData('$CALLTYPE_SINGLE', []),
63+
);
64+
65+
await expect(this.utils.$execSingle(data, EXEC_TYPE_DEFAULT))
66+
.to.emit(this.utils, 'return$execSingle')
67+
.withArgs([ethers.zeroPadBytes(CALL_TYPE_CALL, 32)]);
68+
});
69+
5770
it('reverts when target reverts in default ExecType', async function () {
5871
const value = 0x012;
5972
const data = encodeSingle(
@@ -131,6 +144,17 @@ describe('ERC7579Utils', function () {
131144
await expect(ethers.provider.getBalance(this.anotherTarget)).to.eventually.equal(value2);
132145
});
133146

147+
it('default to calling self is target is address(0) (ERC-7821 calldata compression)', async function () {
148+
const data = encodeBatch(
149+
[ethers.ZeroAddress, 0, this.utils.interface.encodeFunctionData('$CALLTYPE_SINGLE', [])],
150+
[ethers.ZeroAddress, 0, this.utils.interface.encodeFunctionData('$CALLTYPE_BATCH', [])],
151+
);
152+
153+
await expect(this.utils.$execBatch(data, EXEC_TYPE_DEFAULT))
154+
.to.emit(this.utils, 'return$execBatch')
155+
.withArgs([ethers.zeroPadBytes(CALL_TYPE_CALL, 32), ethers.zeroPadBytes(CALL_TYPE_BATCH, 32)]);
156+
});
157+
134158
it('reverts when any target reverts in default ExecType', async function () {
135159
const value1 = 0x012;
136160
const value2 = 0x234;
@@ -193,6 +217,17 @@ describe('ERC7579Utils', function () {
193217
await expect(ethers.provider.getStorage(this.utils.target, slot)).to.eventually.equal(value);
194218
});
195219

220+
it('default to calling self is target is address(0) (ERC-7821 calldata compression)', async function () {
221+
const data = encodeDelegate(
222+
ethers.ZeroAddress,
223+
this.utils.interface.encodeFunctionData('$CALLTYPE_DELEGATECALL', []),
224+
);
225+
226+
await expect(this.utils.$execDelegateCall(data, EXEC_TYPE_DEFAULT))
227+
.to.emit(this.utils, 'return$execDelegateCall')
228+
.withArgs([ethers.zeroPadBytes(CALL_TYPE_DELEGATE, 32)]);
229+
});
230+
196231
it('reverts when target reverts in default ExecType', async function () {
197232
const data = encodeDelegate(this.target, this.target.interface.encodeFunctionData('mockFunctionRevertsReason'));
198233
await expect(this.utils.$execDelegateCall(data, EXEC_TYPE_DEFAULT)).to.be.revertedWith(

0 commit comments

Comments
 (0)