Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@wadealexc
Created October 15, 2019 16:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wadealexc/0f277cf43d11ded83385974a8271846a to your computer and use it in GitHub Desktop.
Save wadealexc/0f277cf43d11ded83385974a8271846a to your computer and use it in GitHub Desktop.
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