Skip to content

Commit a6e6461

Browse files
authored
Merge pull request #339 from sc-forks/test/assembly-if
Add regression test for assembly if blocks
2 parents 3086047 + 547d690 commit a6e6461

File tree

2 files changed

+50
-0
lines changed

2 files changed

+50
-0
lines changed

test/assembly.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,11 @@ describe('generic expressions', () => {
2020
util.report(output.errors);
2121
});
2222

23+
it('should compile after instrumenting an assembly if statement', () => {
24+
const contract = util.getCode('assembly/if.sol');
25+
const info = getInstrumentedVersion(contract, filePath);
26+
const output = JSON.parse(solc.compile(util.codeToCompilerInput(info.contract)));
27+
util.report(output.errors);
28+
});
29+
2330
});

test/sources/assembly/if.sol

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
pragma solidity ^0.5.0;
2+
3+
contract Test {
4+
5+
/// @notice Checks if a given address is whitelisted
6+
/// @return true if address is whitelisted, false if not
7+
function isWhitelisted
8+
(
9+
address _address
10+
)
11+
public
12+
view
13+
returns (bool _isWhitelisted)
14+
{
15+
bytes4 _signature = bytes4(keccak256("whitelisted(address)"));
16+
address _whitelistContract = address(this);
17+
18+
assembly {
19+
let _pointer := mload(0x40) // Set _pointer to free memory pointer
20+
mstore(_pointer, _signature) // Store _signature at _pointer
21+
mstore(add(_pointer, 0x04), _address) // Store _address at _pointer. Offset by 4 bytes for previously stored _signature
22+
23+
// staticcall(g, a, in, insize, out, outsize) => returns 0 on error, 1 on success
24+
let result := staticcall(
25+
gas, // g = gas: whatever was passed already
26+
_whitelistContract, // a = address: _whitelist address assigned from getContractAddress()
27+
_pointer, // in = mem in mem[in..(in+insize): set to _pointer pointer
28+
0x24, // insize = mem insize mem[in..(in+insize): size of signature (bytes4) + bytes32 = 0x24
29+
_pointer, // out = mem out mem[out..(out+outsize): output assigned to this storage address
30+
0x20 // outsize = mem outsize mem[out..(out+outsize): output should be 32byte slot (bool size = 0x01 < slot size 0x20)
31+
)
32+
33+
// Revert if not successful
34+
if iszero(result) {
35+
revert(0, 0)
36+
}
37+
38+
_isWhitelisted := mload(_pointer) // Assign result to returned value
39+
mstore(0x40, add(_pointer, 0x24)) // Advance free memory pointer by largest _pointer size
40+
}
41+
}
42+
}
43+

0 commit comments

Comments
 (0)