|
| 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