Improve Address tests (#4191)

This commit is contained in:
Ernesto García
2023-04-25 13:31:01 +02:00
committed by GitHub
parent 6aac66d065
commit 1a079d258b
3 changed files with 45 additions and 1 deletions

View File

@ -14,6 +14,10 @@ contract CallReceiverMock {
return "0x1234"; return "0x1234";
} }
function mockFunctionEmptyReturn() public payable {
emit MockFunctionCalled();
}
function mockFunctionWithArgs(uint256 a, uint256 b) public payable returns (string memory) { function mockFunctionWithArgs(uint256 a, uint256 b) public payable returns (string memory) {
emit MockFunctionCalledWithArgs(a, b); emit MockFunctionCalledWithArgs(a, b);

View File

@ -59,7 +59,7 @@ library Address {
* IMPORTANT: because control is transferred to `recipient`, care must be * IMPORTANT: because control is transferred to `recipient`, care must be
* taken to not create reentrancy vulnerabilities. Consider using * taken to not create reentrancy vulnerabilities. Consider using
* {ReentrancyGuard} or the * {ReentrancyGuard} or the
* https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*/ */
function sendValue(address payable recipient, uint256 amount) internal { function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance"); require(address(this).balance >= amount, "Address: insufficient balance");

View File

@ -107,6 +107,14 @@ contract('Address', function (accounts) {
await expectEvent.inTransaction(receipt.tx, CallReceiverMock, 'MockFunctionCalled'); await expectEvent.inTransaction(receipt.tx, CallReceiverMock, 'MockFunctionCalled');
}); });
it('calls the requested empty return function', async function () {
const abiEncodedCall = this.target.contract.methods.mockFunctionEmptyReturn().encodeABI();
const receipt = await this.mock.$functionCall(this.target.address, abiEncodedCall);
await expectEvent.inTransaction(receipt.tx, CallReceiverMock, 'MockFunctionCalled');
});
it('reverts when the called function reverts with no reason', async function () { it('reverts when the called function reverts with no reason', async function () {
const abiEncodedCall = this.target.contract.methods.mockFunctionRevertsNoReason().encodeABI(); const abiEncodedCall = this.target.contract.methods.mockFunctionRevertsNoReason().encodeABI();
@ -137,6 +145,11 @@ contract('Address', function (accounts) {
await expectRevert.unspecified(this.mock.$functionCall(this.target.address, abiEncodedCall)); await expectRevert.unspecified(this.mock.$functionCall(this.target.address, abiEncodedCall));
}); });
it('bubbles up error message if specified', async function () {
const errorMsg = 'Address: expected error';
await expectRevert(this.mock.$functionCall(this.target.address, '0x12345678', errorMsg), errorMsg);
});
it('reverts when function does not exist', async function () { it('reverts when function does not exist', async function () {
const abiEncodedCall = web3.eth.abi.encodeFunctionCall( const abiEncodedCall = web3.eth.abi.encodeFunctionCall(
{ {
@ -237,6 +250,11 @@ contract('Address', function (accounts) {
'Address: low-level call with value failed', 'Address: low-level call with value failed',
); );
}); });
it('bubbles up error message if specified', async function () {
const errorMsg = 'Address: expected error';
await expectRevert(this.mock.$functionCallWithValue(this.target.address, '0x12345678', 0, errorMsg), errorMsg);
});
}); });
}); });
@ -277,6 +295,11 @@ contract('Address', function (accounts) {
await expectRevert(this.mock.$functionStaticCall(recipient, abiEncodedCall), 'Address: call to non-contract'); await expectRevert(this.mock.$functionStaticCall(recipient, abiEncodedCall), 'Address: call to non-contract');
}); });
it('bubbles up error message if specified', async function () {
const errorMsg = 'Address: expected error';
await expectRevert(this.mock.$functionCallWithValue(this.target.address, '0x12345678', 0, errorMsg), errorMsg);
});
}); });
describe('functionDelegateCall', function () { describe('functionDelegateCall', function () {
@ -317,5 +340,22 @@ contract('Address', function (accounts) {
await expectRevert(this.mock.$functionDelegateCall(recipient, abiEncodedCall), 'Address: call to non-contract'); await expectRevert(this.mock.$functionDelegateCall(recipient, abiEncodedCall), 'Address: call to non-contract');
}); });
it('bubbles up error message if specified', async function () {
const errorMsg = 'Address: expected error';
await expectRevert(this.mock.$functionCallWithValue(this.target.address, '0x12345678', 0, errorMsg), errorMsg);
});
});
describe('verifyCallResult', function () {
it('returns returndata on success', async function () {
const returndata = '0x123abc';
expect(await this.mock.$verifyCallResult(true, returndata, '')).to.equal(returndata);
});
it('reverts with return data and error m', async function () {
const errorMsg = 'Address: expected error';
await expectRevert(this.mock.$verifyCallResult(false, '0x', errorMsg), errorMsg);
});
}); });
}); });