Implement ERC-7821 calldata compression in ERC7579Utils (#5602)
This commit is contained in:
@ -218,7 +218,9 @@ library ERC7579Utils {
|
||||
uint256 value,
|
||||
bytes calldata data
|
||||
) private returns (bytes memory) {
|
||||
(bool success, bytes memory returndata) = target.call{value: value}(data);
|
||||
(bool success, bytes memory returndata) = (target == address(0) ? address(this) : target).call{value: value}(
|
||||
data
|
||||
);
|
||||
return _validateExecutionMode(index, execType, success, returndata);
|
||||
}
|
||||
|
||||
@ -229,7 +231,7 @@ library ERC7579Utils {
|
||||
address target,
|
||||
bytes calldata data
|
||||
) private returns (bytes memory) {
|
||||
(bool success, bytes memory returndata) = target.delegatecall(data);
|
||||
(bool success, bytes memory returndata) = (target == address(0) ? address(this) : target).delegatecall(data);
|
||||
return _validateExecutionMode(index, execType, success, returndata);
|
||||
}
|
||||
|
||||
|
||||
@ -2,13 +2,14 @@ const { ethers } = require('hardhat');
|
||||
const { expect } = require('chai');
|
||||
const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers');
|
||||
const {
|
||||
CALL_TYPE_CALL,
|
||||
CALL_TYPE_BATCH,
|
||||
CALL_TYPE_DELEGATE,
|
||||
EXEC_TYPE_DEFAULT,
|
||||
EXEC_TYPE_TRY,
|
||||
encodeSingle,
|
||||
encodeBatch,
|
||||
encodeDelegate,
|
||||
CALL_TYPE_CALL,
|
||||
CALL_TYPE_BATCH,
|
||||
encodeMode,
|
||||
} = require('../../helpers/erc7579');
|
||||
const { selector } = require('../../helpers/methods');
|
||||
@ -29,6 +30,14 @@ describe('ERC7579Utils', function () {
|
||||
Object.assign(this, await loadFixture(fixture));
|
||||
});
|
||||
|
||||
it('constants', async function () {
|
||||
await expect(this.utils.$CALLTYPE_SINGLE()).to.eventually.equal(CALL_TYPE_CALL);
|
||||
await expect(this.utils.$CALLTYPE_BATCH()).to.eventually.equal(CALL_TYPE_BATCH);
|
||||
await expect(this.utils.$CALLTYPE_DELEGATECALL()).to.eventually.equal(CALL_TYPE_DELEGATE);
|
||||
await expect(this.utils.$EXECTYPE_DEFAULT()).to.eventually.equal(EXEC_TYPE_DEFAULT);
|
||||
await expect(this.utils.$EXECTYPE_TRY()).to.eventually.equal(EXEC_TYPE_TRY);
|
||||
});
|
||||
|
||||
describe('execSingle', function () {
|
||||
it('calls the target with value', async function () {
|
||||
const value = 0x012;
|
||||
@ -54,6 +63,18 @@ describe('ERC7579Utils', function () {
|
||||
await expect(ethers.provider.getBalance(this.target)).to.eventually.equal(value);
|
||||
});
|
||||
|
||||
it('default to calling self is target is address(0) (ERC-7821 calldata compression)', async function () {
|
||||
const data = encodeSingle(
|
||||
ethers.ZeroAddress, // address(0)
|
||||
0,
|
||||
this.utils.interface.encodeFunctionData('$CALLTYPE_SINGLE', []),
|
||||
);
|
||||
|
||||
await expect(this.utils.$execSingle(data, EXEC_TYPE_DEFAULT))
|
||||
.to.emit(this.utils, 'return$execSingle')
|
||||
.withArgs([ethers.zeroPadBytes(CALL_TYPE_CALL, 32)]);
|
||||
});
|
||||
|
||||
it('reverts when target reverts in default ExecType', async function () {
|
||||
const value = 0x012;
|
||||
const data = encodeSingle(
|
||||
@ -131,6 +152,17 @@ describe('ERC7579Utils', function () {
|
||||
await expect(ethers.provider.getBalance(this.anotherTarget)).to.eventually.equal(value2);
|
||||
});
|
||||
|
||||
it('default to calling self is target is address(0) (ERC-7821 calldata compression)', async function () {
|
||||
const data = encodeBatch(
|
||||
[ethers.ZeroAddress, 0, this.utils.interface.encodeFunctionData('$CALLTYPE_SINGLE', [])],
|
||||
[ethers.ZeroAddress, 0, this.utils.interface.encodeFunctionData('$CALLTYPE_BATCH', [])],
|
||||
);
|
||||
|
||||
await expect(this.utils.$execBatch(data, EXEC_TYPE_DEFAULT))
|
||||
.to.emit(this.utils, 'return$execBatch')
|
||||
.withArgs([ethers.zeroPadBytes(CALL_TYPE_CALL, 32), ethers.zeroPadBytes(CALL_TYPE_BATCH, 32)]);
|
||||
});
|
||||
|
||||
it('reverts when any target reverts in default ExecType', async function () {
|
||||
const value1 = 0x012;
|
||||
const value2 = 0x234;
|
||||
@ -193,6 +225,17 @@ describe('ERC7579Utils', function () {
|
||||
await expect(ethers.provider.getStorage(this.utils.target, slot)).to.eventually.equal(value);
|
||||
});
|
||||
|
||||
it('default to calling self is target is address(0) (ERC-7821 calldata compression)', async function () {
|
||||
const data = encodeDelegate(
|
||||
ethers.ZeroAddress,
|
||||
this.utils.interface.encodeFunctionData('$CALLTYPE_DELEGATECALL', []),
|
||||
);
|
||||
|
||||
await expect(this.utils.$execDelegateCall(data, EXEC_TYPE_DEFAULT))
|
||||
.to.emit(this.utils, 'return$execDelegateCall')
|
||||
.withArgs([ethers.zeroPadBytes(CALL_TYPE_DELEGATE, 32)]);
|
||||
});
|
||||
|
||||
it('reverts when target reverts in default ExecType', async function () {
|
||||
const data = encodeDelegate(this.target, this.target.interface.encodeFunctionData('mockFunctionRevertsReason'));
|
||||
await expect(this.utils.$execDelegateCall(data, EXEC_TYPE_DEFAULT)).to.be.revertedWith(
|
||||
|
||||
Reference in New Issue
Block a user