Created
October 15, 2019 16:29
-
-
Save wadealexc/0f277cf43d11ded83385974a8271846a to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
pragma solidity ^0.5.0; | |
library LibError { | |
function err(address sender, uint amt, string memory password) public pure returns (string memory errMessage) { | |
return string(abi.encodePacked("Call failed, please try again:: ", sender, amt, password)); | |
} | |
} | |
contract Auth { | |
struct AuthStatus { | |
bool status; | |
uint amount; | |
} | |
mapping (address => AuthStatus) authorized; | |
function checkAuthStatus(address sender) public view returns (bool, uint, bytes32) { | |
return (authorized[sender].status, authorized[sender].amount, keccak256(bytes("TOP SECRET"))); | |
} | |
function authorize(uint amount) public { | |
authorized[msg.sender].status = !authorized[msg.sender].status; | |
authorized[msg.sender].amount = amount; | |
} | |
} | |
contract ComeAndTakeIt { | |
address owner; | |
address auth; | |
modifier onlyOwner() { | |
require(msg.sender == owner); | |
_; | |
} | |
constructor() public payable { | |
require(msg.value == 10 wei); | |
owner = msg.sender; | |
auth = address(new Auth()); | |
} | |
function getBal() public view returns (uint) { | |
return address(this).balance; | |
} | |
function adminWithdraw() public onlyOwner { | |
(bool success, ) = msg.sender.call.value(address(this).balance)(""); | |
require(success); | |
} | |
function authorizedWithdraw(uint amount, string memory password) public payable { | |
require(msg.value > address(this).balance / 2); | |
address target = auth; | |
bytes memory data = abi.encodeWithSignature("checkAuthStatus(address)", msg.sender); | |
// Make sure we do not modify state when checking authorization status | |
bool success; | |
assembly { success := staticcall(gas, target, add(32, data), mload(data), 0, 0) } | |
require(success, LibError.err(msg.sender, amount, password)); | |
bytes memory result = getReturndata(); | |
(bool authorized, uint authAmount, bytes32 pHash) = abi.decode(result, (bool, uint, bytes32)); | |
if (authorized && authAmount == amount && amount == address(this).balance && keccak256(bytes(password)) == keccak256(abi.encodePacked(pHash))) { | |
msg.sender.transfer(amount); | |
} | |
} | |
function getReturndataSize() internal pure returns (uint size) { | |
assembly { size := returndatasize } | |
} | |
function getReturndata() internal pure returns (bytes memory data) { | |
data = new bytes(getReturndataSize()); | |
assembly { returndatacopy(add(32, data), 0, mload(data)) } | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment