Last active
May 2, 2020 20:35
-
-
Save JTraversa/cdb23d98755738ff460c3c5805647b34 to your computer and use it in GitHub Desktop.
This file contains hidden or 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.9; | |
pragma experimental ABIEncoderV2; | |
import "./safeMath.sol"; | |
contract DefiHedge { | |
struct RPCSig{ | |
uint8 v; | |
bytes32 r; | |
bytes32 s; | |
} | |
struct EIP712Domain { | |
string name; | |
string version; | |
uint256 chainId; | |
address verifyingContract; | |
} | |
struct Offer{ | |
address maker; | |
address taker; | |
uint256 side; | |
address tokenAddress; | |
uint256 duration; | |
uint256 rate; | |
uint256 interest; | |
uint256 base; | |
bytes makerSignature; | |
bytes makerSalt; | |
bytes takerSignature; | |
} | |
bytes32 DOMAIN_SEPARATOR; | |
constructor () public { | |
DOMAIN_SEPARATOR = hashDomain(EIP712Domain({ | |
name: "DefiHedge", | |
version: '1', | |
chainId: 3, | |
verifyingContract: 0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC | |
})); | |
} | |
using SafeMath for uint; | |
bytes32 constant EIP712DOMAIN_TYPEHASH = keccak256( | |
"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)" | |
); | |
bytes32 constant OFFER_TYPEHASH = keccak256( | |
"Offer(address maker,address taker,uint256 side,address tokenAddress,uint256 duration,uint256 rate,uint256 interest,uint256 base,uint256 state,bytes makerSalt,bytes makerSignature,bytes takerSignature)" | |
); | |
function hashDomain(EIP712Domain memory eip712Domain) internal pure returns (bytes32) { | |
return keccak256(abi.encode( | |
EIP712DOMAIN_TYPEHASH, | |
keccak256(bytes(eip712Domain.name)), | |
keccak256(bytes(eip712Domain.version)), | |
eip712Domain.chainId, | |
eip712Domain.verifyingContract | |
)); | |
} | |
function hashSignedOffer(Offer memory signedOffer)private pure returns(bytes32){ | |
return keccak256(abi.encode( | |
OFFER_TYPEHASH, | |
signedOffer.maker, | |
signedOffer.taker, | |
signedOffer.side, | |
signedOffer.tokenAddress, | |
signedOffer.duration, | |
signedOffer.rate, | |
signedOffer.interest, | |
signedOffer.base, | |
signedOffer.makerSalt, | |
signedOffer.makerSignature, | |
signedOffer.takerSignature | |
)); | |
} | |
function verify(address maker, address taker, uint256 side, address tokenAddress, uint256 duration, uint256 rate, uint256 interest, uint256 base, bytes memory makerSalt, bytes memory makerSignature, bytes memory takerSignature) public view returns (address, address) { | |
// Note: we need to use `encodePacked` here instead of `encode`. | |
Offer memory signedOffer = Offer( | |
maker, | |
taker, | |
side, | |
tokenAddress, | |
duration, | |
rate, | |
interest, | |
base, | |
makerSalt, | |
makerSignature, | |
"0x000000000000000000000000000000000000000000000" | |
); | |
bytes32 digest = keccak256(abi.encodePacked( | |
"\x19\x01", | |
DOMAIN_SEPARATOR, | |
hashSignedOffer(signedOffer) | |
)); | |
RPCSig memory RPCsig = signatureRPC(takerSignature); | |
return (ecrecover(digest, RPCsig.v, RPCsig.r, RPCsig.s), taker); | |
} | |
/// Return RSV/ensure signature is parsing correctly | |
function signatureRPCtest(bytes memory sig)public view returns (bytes32 R, bytes32 S, uint8 v){ | |
bytes32 r; | |
bytes32 s; | |
uint8 v; | |
if (sig.length != 65) { | |
return ('Length', 'Length', 0); | |
} | |
assembly { | |
r := mload(add(sig, 32)) | |
s := mload(add(sig, 64)) | |
v := and(mload(add(sig, 65)), 255) | |
} | |
if (v == 39 || v == 40) { | |
v = v-12; | |
} | |
if (v != 27 && v != 28) { | |
return ('V Error', 'V Error', 0); | |
} | |
return (r,s,v); | |
} | |
/// Parses signature into RSV | |
function signatureRPC(bytes memory sig)internal pure returns (RPCSig memory RPCsig){ | |
bytes32 r; | |
bytes32 s; | |
uint8 v; | |
if (sig.length != 65) { | |
return RPCSig(0,'0','0'); | |
} | |
assembly { | |
r := mload(add(sig, 32)) | |
s := mload(add(sig, 64)) | |
v := and(mload(add(sig, 65)), 255) | |
} | |
if (v < 27) { | |
v += 27; | |
} | |
if (v == 39 || v == 40) { | |
v = v-12; | |
} | |
if (v != 27 && v != 28) { | |
return RPCSig(0,'0','0'); | |
} | |
return RPCSig(v,r,s); | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment