forked from OpenZeppelin/openzeppelin-contracts
-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathSimulatedCall.test.js
More file actions
101 lines (82 loc) · 4.04 KB
/
SimulatedCall.test.js
File metadata and controls
101 lines (82 loc) · 4.04 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
const { ethers } = require('hardhat');
const { expect } = require('chai');
const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers');
const value = 42n;
async function fixture() {
const [receiver, other] = await ethers.getSigners();
const mock = await ethers.deployContract('$SimulateCall');
const simulator = ethers.getCreate2Address(
mock.target,
ethers.ZeroHash,
ethers.keccak256(
ethers.concat([
'0x60315f8160095f39f3',
'0x60333611600a575f5ffd5b6034360360345f375f5f603436035f6014355f3560601c5af13d5f5f3e5f3d91602f57f35bfd',
]),
),
);
const target = await ethers.deployContract('$CallReceiverMock');
// fund the mock contract (for tests that use value)
await other.sendTransaction({ to: mock, value });
return { mock, target, receiver, other, simulator };
}
describe('SimulateCall', function () {
beforeEach(async function () {
Object.assign(this, await loadFixture(fixture));
});
it('automatic simulator deployment', async function () {
await expect(ethers.provider.getCode(this.simulator)).to.eventually.equal('0x');
// First call performs deployment
await expect(this.mock.$getSimulator()).to.emit(this.mock, 'return$getSimulator').withArgs(this.simulator);
await expect(ethers.provider.getCode(this.simulator)).to.eventually.not.equal('0x');
// Following calls use the same simulator
await expect(this.mock.$getSimulator()).to.emit(this.mock, 'return$getSimulator').withArgs(this.simulator);
});
describe('simulated call', function () {
it('target success', async function () {
const txPromise = this.mock.$simulateCall(
ethers.Typed.address(this.target),
ethers.Typed.bytes(this.target.interface.encodeFunctionData('mockFunctionWithArgsReturn', [10, 20])),
);
await expect(txPromise).to.changeEtherBalances([this.mock, this.simulator, this.target], [0n, 0n, 0n]);
await expect(txPromise)
.to.emit(this.mock, 'return$simulateCall_address_bytes')
.withArgs(true, ethers.AbiCoder.defaultAbiCoder().encode(['uint256', 'uint256'], [10, 20]))
.to.not.emit(this.target, 'MockFunctionCalledWithArgs');
});
it('target success (with value)', async function () {
// perform simulated call
const txPromise = this.mock.$simulateCall(
ethers.Typed.address(this.target),
ethers.Typed.uint256(value),
ethers.Typed.bytes(this.target.interface.encodeFunctionData('mockFunctionExtra')),
);
await expect(txPromise).to.changeEtherBalances([this.mock, this.simulator, this.target], [0n, 0n, 0n]);
await expect(txPromise)
.to.emit(this.mock, 'return$simulateCall_address_uint256_bytes')
.withArgs(true, ethers.AbiCoder.defaultAbiCoder().encode(['address', 'uint256'], [this.mock.target, value]))
.to.not.emit(this.target, 'MockFunctionCalledExtra');
});
it('target revert', async function () {
const txPromise = this.mock.$simulateCall(
ethers.Typed.address(this.target),
ethers.Typed.bytes(this.target.interface.encodeFunctionData('mockFunctionRevertsReason')),
);
await expect(txPromise).to.changeEtherBalances([this.mock, this.simulator, this.target], [0n, 0n, 0n]);
await expect(txPromise)
.to.emit(this.mock, 'return$simulateCall_address_bytes')
.withArgs(false, this.target.interface.encodeErrorResult('Error', ['CallReceiverMock: reverting']));
});
it('target revert (with value)', async function () {
const txPromise = this.mock.$simulateCall(
ethers.Typed.address(this.target),
ethers.Typed.uint256(value),
ethers.Typed.bytes(this.target.interface.encodeFunctionData('mockFunctionRevertsReason')),
);
await expect(txPromise).to.changeEtherBalances([this.mock, this.simulator, this.target], [0n, 0n, 0n]);
await expect(txPromise)
.to.emit(this.mock, 'return$simulateCall_address_uint256_bytes')
.withArgs(false, this.target.interface.encodeErrorResult('Error', ['CallReceiverMock: reverting']));
});
});
});