mapping (address => uint256) public replayNonce;
function metaApprove(address spender, uint256 value, uint256 nonce, uint256 reward, bytes signature) public returns (bool) {
require(spender != address(0));
bytes32 metaHash = metaApproveHash(spender,value,nonce,reward);
address signer = getSigner(metaHash,signature);
require(nonce == replayNonce[signer]);
replayNonce[signer]++;
_allowed[signer][spender] = value;
if(reward>0){
_transfer(signer, msg.sender, reward);
}
emit Approval(msg.sender, spender, value);
return true;
}
function _approve(address owner, address spender, uint256 value) internal {
require(owner != address(0), "ERC20: approve from the zero address");
require(spender != address(0), "ERC20: approve to the zero address");
_allowances[owner][spender] = value;
emit Approval(owner, spender, value);
}
function metaApproveHash(address spender, uint256 value, uint256 nonce, uint256 reward) public view returns(bytes32){
return keccak256(abi.encodePacked(address(this),"metaApprove" spender, value, nonce, reward));
}
function getSigner(bytes32 _hash, bytes _signature) internal pure returns (address){
bytes32 r;
bytes32 s;
uint8 v;
if (_signature.length != 65) {
return address(0);
}
assembly {
r := mload(add(_signature, 32))
s := mload(add(_signature, 64))
v := byte(0, mload(add(_signature, 96)))
}
if (v < 27) {
v += 27;
}
if (v != 27 && v != 28) {
return address(0);
} else {
return ecrecover(keccak256(
abi.encodePacked("\x19Ethereum Signed Message:\n32", _hash)
), v, r, s);
}
}
Last active
July 3, 2019 12:55
-
-
Save andreafspeziale/60b5bde3cd0806868e885df9be46864e to your computer and use it in GitHub Desktop.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment