[v1] Circuit and contract cleanup (#25)

* Add claimId as input to circuit

* Add nullifier

* Add max amount functionality

* Add claim_id to gen_input

* Update scripts to use random entropy

* Add input.json

* Add gen verifier contract server script

* Add new verifier contract

* Fix contract bugs; Add tests

* update scripts
This commit is contained in:
Sachin
2023-05-16 17:03:49 +05:30
committed by GitHub
parent c50e9aa005
commit 3b2380fbfa
14 changed files with 203 additions and 106 deletions

View File

@@ -40,6 +40,7 @@ export interface ICircuitInputs {
venmo_offramper_id_idx?: string;
venmo_amount_idx?: string;
order_id?: string;
claim_id?: string;
}
enum CircuitType {
@@ -73,6 +74,7 @@ export async function getCircuitInputs(
body: Buffer,
body_hash: string,
order_id: string,
claim_id: string,
circuit: CircuitType
): Promise<{
valid: {
@@ -170,6 +172,7 @@ export async function getCircuitInputs(
venmo_offramper_id_idx,
venmo_amount_idx,
order_id,
claim_id
};
} else {
assert(circuit === CircuitType.SHA, "Invalid circuit type");
@@ -185,7 +188,7 @@ export async function getCircuitInputs(
};
}
export async function generate_inputs(email: Buffer, order_id: string): Promise<ICircuitInputs> {
export async function generate_inputs(email: Buffer, order_id: string, claim_id: string): Promise<ICircuitInputs> {
var result;
console.log("DKIM verification starting");
result = await dkimVerify(email);
@@ -223,14 +226,14 @@ export async function generate_inputs(email: Buffer, order_id: string): Promise<
let pubkey = result.results[0].publicKey;
const pubKeyData = pki.publicKeyFromPem(pubkey.toString());
let modulus = BigInt(pubKeyData.n.toString());
let fin_result = await getCircuitInputs(sig, modulus, message, body, body_hash, order_id, circuitType);
let fin_result = await getCircuitInputs(sig, modulus, message, body, body_hash, order_id, claim_id, circuitType);
return fin_result.circuitInputs;
}
async function do_generate() {
const email = fs.readFileSync(email_file);
// console.log(email);
const gen_inputs = await generate_inputs(email, "0");
const gen_inputs = await generate_inputs(email, "1", "0");
// console.log(JSON.stringify(gen_inputs));
return gen_inputs;
}

View File

@@ -286,18 +286,25 @@ template P2POnrampVerify(max_header_bytes, max_body_bytes, n, k) {
reveal_packed[i] <== packed_output[i].out;
}
// Nullifier
// Packed SHA256 hash of the email header and body hash (the part that is signed upon)
signal output nullifier[msg_len];
for (var i = 0; i < msg_len; i++) {
nullifier[i] <== base_msg[i].out;
}
// The following signals do not take part in computation
signal input order_id;
signal input claim_id;
signal order_id_squared;
signal claim_id_squared;
// Add constraint to tie the proof to a specific order_id to prevent replay attacks and frontrunning.
// Add constraint to tie the proof to a specific (order_id, claim_id) to prevent replay attacks and frontrunning.
order_id_squared <== order_id * order_id;
// TOTAL CONSTRAINTS: TODO
// TODO total signals
claim_id_squared <== claim_id * claim_id;
}
// In circom, all output signals of the main component are public (and cannot be made private), the input signals of the main component are private if not stated otherwise using the keyword public as above. The rest of signals are all private and cannot be made public.
// This makes modulus and reveal_venmo_user_packed public. hash(signature) can optionally be made public, but is not recommended since it allows the mailserver to trace who the offender is.
component main { public [ modulus, order_id ] } = P2POnrampVerify(1024, 6400, 121, 17);
component main { public [ modulus, order_id, claim_id ] } = P2POnrampVerify(1024, 6400, 121, 17);

File diff suppressed because one or more lines are too long

View File

@@ -8,10 +8,11 @@ exec &> >(tee -a test_log.out)
PATH_TO_CIRCUIT=${1:-./circuit} # First argument $1 is path to circuit directory
PARTIAL_ZKEYS=${2:-./partial_zkeys} # Second argument $2 is path to partial zkeys directory (Relative to PATH_TO_CIRCUIT)
CIRCUIT_NAME=${2:-circuit} # Second argument $2 is circuit name
SKIP_PHASE2_CONTRIBUTION=${3:-true} # Third argument $3 is true/false whether to skip phase 2 contribution. Setting to true is unsafe but can be for testing. Otherwise, set to false
PHASE1=$HOME/ptau_files/powersOfTau28_hez_final_${4:-23}.ptau # Fourth argument $4 is ptau file number
SKIP_ZKEY_VERIFICATION=${5:-true} # Fifth argument $5 is true/false whether to skip zkey verification
CIRCUIT_NAME=${3:-circuit} # Second argument $3 is circuit name
SKIP_PHASE2_CONTRIBUTION=${4:-true} # Third argument $4 is true/false whether to skip phase 2 contribution. Setting to true is unsafe but can be for testing. Otherwise, set to false
RANDOM_ENTROPY=${5:-"some random text for entropy"} # Fourth argument $5 is random entropy
PHASE1=$HOME/ptau_files/powersOfTau28_hez_final_${6:-23}.ptau # Fourth argument $6 is ptau file number
SKIP_ZKEY_VERIFICATION=${7:-true} # Fifth argument $7 is true/false whether to skip zkey verification
echo $PWD
echo "****NOTE****"

View File

@@ -0,0 +1,3 @@
# Turn the verifier into a smart contract
cd circuit
$SNARKJS_PATH zkey export solidityverifier circuit.zkey ../contracts/Verifier.sol

View File

@@ -9,8 +9,9 @@ exec &> >(tee -a test_log.out)
PATH_TO_CIRCUIT=${1:-./circuit} # First argument $1 is path to circuit directory
CIRCUIT_NAME=${2:-circuit} # Second argument $2 is circuit name
SKIP_PHASE2_CONTRIBUTION=${3:-true} # Third argument $3 is true/false whether to skip phase 2 contribution. Setting to true is unsafe but can be for testing. Otherwise, set to false
PHASE1=$HOME/ptau_files/powersOfTau28_hez_final_${4:-23}.ptau # Fourth argument $4 is ptau file number
SKIP_ZKEY_VERIFICATION=${5:-true} # Fifth argument $5 is true/false whether to skip zkey verification
RANDOM_ENTROPY=${4:-"some random text for entropy"} # Fourth argument $4 is random entropy
PHASE1=$HOME/ptau_files/powersOfTau28_hez_final_${5:-23}.ptau # Fourth argument $5 is ptau file number
SKIP_ZKEY_VERIFICATION=${6:-true} # Fifth argument $6 is true/false whether to skip zkey verification
echo $PWD
# if [ ! $# -eq 5 ]; # Check if there are 5 arguments
@@ -44,7 +45,7 @@ else
echo "****CONTRIBUTE TO PHASE 2 CEREMONY****"
start=`date +%s`
$NODE_PATH $SNARKJS_PATH zkey contribute -verbose "$CIRCUIT_NAME"_0.zkey "$CIRCUIT_NAME".zkey -n="First phase2 contribution" -e="some random text for entropy"
$NODE_PATH $SNARKJS_PATH zkey contribute -verbose "$CIRCUIT_NAME"_0.zkey "$CIRCUIT_NAME".zkey -n="First phase2 contribution" -e="$RANDOM_ENTROPY"
end=`date +%s`
echo "DONE ($((end-start))s)"
fi

View File

@@ -33,7 +33,7 @@ def upload_to_s3(filename, dir=""):
with open(dir + filename, 'rb') as file:
print("Starting upload...")
s3.upload_fileobj(file, bucket_name, filename, ExtraArgs={
# 'ACL': 'public-read', 'ContentType': 'binary/octet-stream'
'ACL': 'public-read', 'ContentType': 'binary/octet-stream'
})
print("Done uploading ", filename, "!")

View File

@@ -1,3 +1,4 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.12;
import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol";

View File

@@ -1,14 +1,14 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.12;
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol";
import { Verifier } from "./Verifier.sol";
import "hardhat/console.sol";
// Todo:
// 1. Add nullifier logic.
// 2. Add claimId to signals.
contract Ramp is Verifier {
contract Ramp is Verifier, Ownable {
/* ============ Enums ============ */
@@ -55,11 +55,14 @@ contract Ramp is Verifier {
/* ============ Public Variables ============ */
uint256 private constant rsaModulusChunksLen = 17;
uint16 private constant msgLen = 22;
uint16 private constant msgLen = 26;
uint16 private constant bytesInPackedBytes = 7; // 7 bytes in a packed item returned from circom
/* ============ Public Variables ============ */
// Max value for the order amount, claim amount, and off-chain transaction amount
uint256 public maxAmount;
IERC20 public immutable usdc;
uint256[rsaModulusChunksLen] public venmoMailserverKeys;
@@ -70,15 +73,28 @@ contract Ramp is Verifier {
mapping(uint256=>mapping(uint256=>bool)) public orderClaimedByVenmoId;
mapping(uint256=>mapping(uint256=>OrderClaim)) public orderClaims;
mapping(bytes32 => bool) public nullified;
/* ============ External Functions ============ */
constructor(uint256[rsaModulusChunksLen] memory _venmoMailserverKeys, IERC20 _usdc) {
constructor(uint256[rsaModulusChunksLen] memory _venmoMailserverKeys, IERC20 _usdc, uint256 _maxAmount) {
venmoMailserverKeys = _venmoMailserverKeys;
usdc = _usdc;
maxAmount = _maxAmount;
orderNonce = 1;
}
/* ============ Admin Functions ============ */
function setMaxAmount(uint256 _maxAmount) external onlyOwner {
maxAmount = _maxAmount;
}
function setVenmoMailserverKeys(uint256[rsaModulusChunksLen] memory _venmoMailserverKeys) external onlyOwner {
venmoMailserverKeys = _venmoMailserverKeys;
}
/* ============ External Functions ============ */
@@ -86,7 +102,9 @@ contract Ramp is Verifier {
external
{
require(_amount != 0, "Amount can't be 0");
require(_amount <= maxAmount, "Amount can't be greater than max amount");
require(_maxAmountToPay != 0, "Max amount can't be 0");
require(_maxAmountToPay <= maxAmount, "Max amount can't be greater than max amount");
Order memory order = Order({
onRamper: msg.sender,
@@ -114,6 +132,9 @@ contract Ramp is Verifier {
require(!orderClaimedByVenmoId[_orderNonce][_venmoId], "Order has already been claimed by Venmo ID");
// Todo: This can be sybilled. What are the implications of this?
require(msg.sender != orders[_orderNonce].onRamper, "Can't claim your own order");
require(_minAmountToPay != 0, "Min amount to pay can't be 0");
require(_minAmountToPay <= orders[_orderNonce].maxAmountToPay, "Min amount to pay can't be greater than max amount to pay");
OrderClaim memory claim = OrderClaim({
offRamper: msg.sender,
@@ -137,13 +158,12 @@ contract Ramp is Verifier {
uint256[2] memory _a,
uint256[2][2] memory _b,
uint256[2] memory _c,
uint256[msgLen] memory _signals,
uint256 claimId
uint256[msgLen] memory _signals
)
external
{
// Verify that proof generated by onRamper is valid
(uint256 offRamperVenmoId, uint256 amount, uint256 orderId) = _verifyAndParseOnRampProof(_a, _b, _c, _signals);
(uint256 offRamperVenmoId, uint256 amount, uint256 orderId, uint256 claimId, bytes32 nullifier) = _verifyAndParseOnRampProof(_a, _b, _c, _signals);
// require it is an open order
require(orders[orderId].status == OrderStatus.Open, "Order has already been filled, canceled, or doesn't exist");
@@ -159,12 +179,16 @@ contract Ramp is Verifier {
);
// Require that the amount paid by on-ramper >= minAskAmount of the off-ramper
// Do not require amount to be less than maxAmount because if the on-ramper wants to pay more, they can
// and we let the transaction go through.
require(amount >= orderClaims[orderId][claimId].minAmountToPay, "Amount paid off-chain is too low");
// Update order claim status
orderClaims[orderId][offRamperVenmoId].status = ClaimStatus.Used;
// Update order filled status
orders[orderId].status = OrderStatus.Filled;
// Update nullifier status
nullified[nullifier] = true;
usdc.transfer(orders[orderId].onRamper, orders[orderId].amountToReceive);
}
@@ -235,7 +259,7 @@ contract Ramp is Verifier {
)
internal
view
returns (uint256 offRamperVenmoId, uint256 usdAmount, uint256 orderId)
returns (uint256 offRamperVenmoId, uint256 usdAmount, uint256 orderId, uint256 claimId, bytes32 nullifier)
{
require(verifyProof(a, b, c, signals), "Invalid Proof"); // checks effects iteractions, this should come first
@@ -250,13 +274,23 @@ contract Ramp is Verifier {
uint256 amount = _stringToUint256(_convertPackedBytesToBytes(amountSignals, bytesInPackedBytes * 3));
usdAmount = amount * 10 ** 6;
// Signals [4:21] are modulus.
for (uint256 i = 4; i < msgLen - 1; i++) {
require(signals[i] == venmoMailserverKeys[i - 4], "Invalid: RSA modulus not matched");
// Signals [4, 5, 6] are nullifier
bytes memory nullifierAsBytes = abi.encodePacked(
signals[4], signals[5], signals[6]
);
nullifier = keccak256(nullifierAsBytes);
require(!nullified[nullifier], "Email has already been used");
// Signals [7, 8, ...., 23] are modulus.
for (uint256 i = 7; i < msgLen - 2; i++) {
require(signals[i] == venmoMailserverKeys[i - 7], "Invalid: RSA modulus not matched");
}
// Signals [22] is orderId
orderId = signals[msgLen - 1];
// Signals [24] is orderId
orderId = signals[msgLen - 2];
// Signals [25] is claimId
claimId = signals[msgLen - 1];
}
// Unpacks uint256s into bytes and then extracts the non-zero characters

View File

@@ -194,126 +194,146 @@ contract Verifier {
8495653923123431417604973247489272438418190587263600148770280649306958101930]
);
vk.delta2 = Pairing.G2Point(
[11559732032986387107991004021392285783925812861821192530917403151452391805634,
10857046999023057135944570762232829481370756359578518086990519993285655852781],
[4082367875863433681332203403145435568316851327593401208105741076214120093531,
8495653923123431417604973247489272438418190587263600148770280649306958101930]
[5721570614151672599826450111040049224517613686826545938660438537133075082495,
14926436212468659221459641623674644759850737624925086968534525009292852833701],
[8361611497686971799563668582861435472903677552488431954757944389462903866092,
7466664899953344669362145962588530845983876490495119165444640776557989651680]
);
vk.IC = new Pairing.G1Point[](23);
vk.IC = new Pairing.G1Point[](27);
vk.IC[0] = Pairing.G1Point(
6345625035907007648647156631169141088668972260668696632485644746448631142189,
1787315389787281838713000160863555858825923346728574045670827674545223356873
11390303289064284098189744438463447420778707582462791052618307568031589832040,
7449448169535529458378919271505148978539356638415795572750354322373068439362
);
vk.IC[1] = Pairing.G1Point(
6481079754661805137094215791254594040526184600722376422737734066452700325008,
14478900998572844270619881316564617332379122408117952561896108901687289677566
12926512673301137570628263349765214889130631160950332406024037635286650507630,
8992052977473807772447083576919945335702173772905787498293268627890617242997
);
vk.IC[2] = Pairing.G1Point(
13078721267399733136104397467931858852312237676548921972484381996942250265624,
1748362704799022523045626152552407438343668507036909329650266569364111474548
10300435939865091196742379379501283306448703934998001867487926349042531050125,
14928439355818328326375363823537703358818022931799429941075037725307577070455
);
vk.IC[3] = Pairing.G1Point(
16026021957911126231871741969427339165838878554367146057141338861638364356751,
14899842232710115590584291789659822373625055087000286386690104969729505203421
7611413456733281848700061561983325504251513662385561049933512147189344189699,
4833185216270508713342192501912663935130269443612842251206521878230971676839
);
vk.IC[4] = Pairing.G1Point(
3459274320194134980691712564314463162998204890691720802181168727959265335347,
1856100767067364945173324162067892118351874712509717865013639661918917421436
19062247490960708321777748170389762379672856148924642110378887144213419852566,
6239888245029187530537044168742210282838199991619156575647864448012631067705
);
vk.IC[5] = Pairing.G1Point(
1730444199711333500395095785167457505870281644144361482951649936018115451752,
16226268759548605823710600834485279199665235997004958382986126351109032752483
1900533091959672810586142219238009988575950672610752410245631793102644183020,
8209782988030410782646465527164053824222196574783486141746214338752832758379
);
vk.IC[6] = Pairing.G1Point(
19693053407616006957481533930062002091207976596954481348371563657186692999107,
2422115246455710536663030586327174053850787031521558802255774727333170764990
8878510019023174601370916887464135804425456732601707876870283071941319158779,
2238933498147138257708057025060058512632744467048518254794891840583200928651
);
vk.IC[7] = Pairing.G1Point(
1730766938889407647923999986620339979499937171002354848783020719561602547245,
20989413897612581233663112095041318913772751778938307255977490127650098239397
14774264761588045430490817263961834820949201219760292402883462377258134489261,
13565063219270278023061572736709176503347437541058744868567068106406233758095
);
vk.IC[8] = Pairing.G1Point(
16096236096969834003363255557530577452105879870517371051299177659344588245642,
11016926842125500078143335165384340593271927876114865061774170616605750243943
8640222970343729307611189667179627998087825168565600334875558967992577664369,
14110274253571946477699011561265474162427343516115444871710303863258194976702
);
vk.IC[9] = Pairing.G1Point(
912588438640122827702224830823957577427687103017226829806255537482538236749,
14506165070853943179142981873721171315873100015557892017445119945526800972321
2595280839257795204498281112565360451329597440214622571669060445042599277667,
12806000801103941363924896892277761387543153396726070951416512053768776176473
);
vk.IC[10] = Pairing.G1Point(
19155326942805100303993822197947492949549549284140388423401998288471551241004,
2989856601230819588216329628277357426936058248756038872661629984824418086319
16097556813974149893401667692330725086078736852759927722019755388159570888179,
21041500172099620828948779396096271241391891618911735365565777088038720129820
);
vk.IC[11] = Pairing.G1Point(
21280170726486817487312224345511317145948992080653671886934907575710969743816,
15894920146550642135776769199672872793201486012392802614785969357619073685875
8502891934148992894234766665284434965333422143486619420599160188496289298766,
10432356863447150028693163504190402489144219087927812414716985309187094963373
);
vk.IC[12] = Pairing.G1Point(
18247661317814424051975777883262158280537289325594639844496358549019663333917,
17014806579915553870231245786729397480386549400768158302613592457656887708700
7657191410121949604532752880122711166479708868216582440269748853989575610007,
20010265458375447628489286987142310761594415204146061186951685402842014748556
);
vk.IC[13] = Pairing.G1Point(
20568796218682820824651100596398886705201298927906778865008954050174894404079,
12042528113145583017392662339832748861254432418227407729026212398503647124752
4109233900831522958415334035503369207374528764471261924191406262792133590161,
3446961700970273147427294976869718002542009503298635780540177324259631759666
);
vk.IC[14] = Pairing.G1Point(
4028153745169543163879509240579809741046959237513344424412121809703092913923,
4956636485317965387215132679787035575794606059879788203613024863777084420899
2999051556079069777151853990146500844490545822224819880971649206202307535626,
20767119344253261102966821628433281607825360200248254451575874541861067020033
);
vk.IC[15] = Pairing.G1Point(
8388266276329007471926750296996871151174172972228897996484654434783673927513,
11169663729961788661922834650406315553152733025572631400631085297338490960974
12935231153420133683806436064217241608814572033955662233616391592624581848743,
758401520845175001964281383234391730940870430820194255681311894447544715649
);
vk.IC[16] = Pairing.G1Point(
19816133709997441768288395143485336933280600313049868120897520205972980675830,
7333930147927869277976604339105623489898859013027854438129711446699927520200
16944115134472787995924248861831098501730291888520747962165860185180158785640,
20166735440122921194353354674357418838459453043867299035185577606103206863362
);
vk.IC[17] = Pairing.G1Point(
2344724007319275687509189588379536155087652120202331489455364019710103875209,
21165256966404429511503777843413167611105181434391117805991246364676409818938
16370904269034995920740050962123727789402746519779569403976467135105461698075,
14449271159026100159899871807797201759680724040929735003794398191584825703054
);
vk.IC[18] = Pairing.G1Point(
16368511732038242935059387762639104327852612375336651550576425114765462535588,
2534416221208314662118272094432020426361494011657258553424619070823358408751
4575501916420720895898002167414775436285619437696512628470738161818319565343,
10259221667769872405798976776109799802312224894204101284658645978943530534476
);
vk.IC[19] = Pairing.G1Point(
13764453553277278689227469029995344301656204701265967126182493651522396330567,
12241658532931211106624637717325385821414629302218402555952478265435877298493
9466546245760905072516718698902616405319448266431304502642473889515878674758,
386151568081870823815772299620009618170598555506537057870884344002746885784
);
vk.IC[20] = Pairing.G1Point(
2748877456320013647824052577299298304187048968519478155789387350162714782453,
576147530236029344786636454909833636851066704921361893573883237732088900322
18647704995794871178778602066785346048858539589664585854089930952033006245268,
10882072269148921751625569635653085812004835078077584218985179564268085978911
);
vk.IC[21] = Pairing.G1Point(
2281517192421323523825805947356085443004900248370246265521865024259142339195,
3608767008194600532587119271894966784361157514137997128405667071034023454069
12906617616864950231846033602870348293620432768295722554148786123483296821895,
1158115217019412570000102563141115303282553866405915609770644931957018820227
);
vk.IC[22] = Pairing.G1Point(
19148594851313147837429178582622251468850707709003332003350289345127800690706,
495678507691324991329551155843585784572260275366007291543234995152160315655
13492979305308929563551152505636677944284946254909375630290488183092914383791,
5668308865271279078741142041312696139694684618169069800309774365915338294251
);
vk.IC[23] = Pairing.G1Point(
19681564751580133075178966086563939560874013276462995931505512780075917133605,
18685571392392720007478153403859740179162471232692219332488240021841431745434
);
vk.IC[24] = Pairing.G1Point(
1203894112246763981503775595446451605566087080761837686069627560297854656668,
20983175836380296359503289678772223830103177744618018883025803258327256687406
);
vk.IC[25] = Pairing.G1Point(
8397350471530151972463810941539235606086258406954526704957458659889110597164,
18619678220471645118400912559060396310227095241324996845404332354319999198988
);
vk.IC[26] = Pairing.G1Point(
4232527691538139375507463951561828769485123236480968421402897242256613017100,
19678596330709811800920113509694996785802586222249736560235061199800316957842
);
}
@@ -341,7 +361,7 @@ contract Verifier {
uint[2] memory a,
uint[2][2] memory b,
uint[2] memory c,
uint[22] memory input
uint[26] memory input
) public view returns (bool r) {
Proof memory proof;
proof.A = Pairing.G1Point(a[0], a[1]);

View File

@@ -34,5 +34,13 @@ module.exports = {
paths: {
artifacts: "./artifacts",
},
solidity: "0.8.12",
solidity: {
version: "0.8.12",
settings: {
optimizer: {
enabled: true,
runs: 200
}
}
}
};

View File

@@ -27,7 +27,8 @@
"circuitStats": "bash ./circuit/scripts/circuit_stats.sh",
"genChunkedZkeyServer": "bash ./circuit/server-scripts/generate_chunked_keys_phase2_groth16.sh",
"genVkeyServer": "bash ./circuit/server-scripts/generate_verification_key.sh",
"uploadChunkedKeys": "python3 ./circuit/server-scripts/upload_to_s3.py"
"uploadChunkedKeys": "python3 ./circuit/server-scripts/upload_to_s3.py",
"genContractServer": "bash ./circuit/server-scripts/generate_contract.sh && yarn bumpSolidity"
},
"keywords": [],
"author": "",

View File

@@ -14,12 +14,13 @@ async function main() {
console.log("Deploying Fake USDC contract with the account:", deployer.address);
const FakeUSDC = await hre.ethers.getContractFactory("FakeUSDC");
const fakeUSDC = await FakeUSDC.deploy("Fake USDC", "fUSDC", 10000000000000, deployGasConfig);
// const FakeUSDC = await hre.ethers.getContractFactory("FakeUSDC");
// const fakeUSDC = await FakeUSDC.deploy("Fake USDC", "fUSDC", 10000000000000, deployGasConfig);
console.log("FakeUSDC contract deployed to address:", fakeUSDC.address);
// console.log("FakeUSDC contract deployed to address:", fakeUSDC.address);
const fakeUSDCAddress = "0xf6426A1fdE02c3d6f10b4af107cDd7669574E74C";
const maxAmount = BigNumber.from("10000000"); // $10
const venmoRsaKey = [
"683441457792668103047675496834917209",
"1011953822609495209329257792734700899",
@@ -43,7 +44,7 @@ async function main() {
console.log("Deploying Ramp contract with the account:", deployer.address);
const Ramp = await hre.ethers.getContractFactory("Ramp");
const ramp = await Ramp.deploy(venmoRsaKey, fakeUSDCAddress, deployGasConfig);
const ramp = await Ramp.deploy(venmoRsaKey, fakeUSDCAddress, maxAmount, deployGasConfig);
console.log("Ramp contract deployed to address:", ramp.address);
}

View File

@@ -33,6 +33,7 @@ const ZERO = BigNumber.from(0);
describe("Ramp", function () {
let ramp;
let fakeUSDC;
let maxAmount;
let deployer;
let onRamper;
@@ -47,16 +48,17 @@ describe("Ramp", function () {
await fakeUSDC.connect(deployer).transfer(offRamper.address, 1000000000); // $1000
const Ramp = await hre.ethers.getContractFactory("Ramp");
ramp = await Ramp.deploy(venmoRsaKey, fakeUSDC.address);
maxAmount = BigNumber.from("10000000");
ramp = await Ramp.deploy(venmoRsaKey, fakeUSDC.address, maxAmount);
});
describe("postOrder", function () {
let amount = BigNumber.from(100000000); // $100
let maxAmountToPay = BigNumber.from(110000000); // $110
let amount = BigNumber.from(9000000); // $9
let maxAmountToPay = BigNumber.from(10000000); // $10
it("stores an order", async function () {
const publicKey = "a19eb5cdd6b3fce15832521908e4f66817e9ea8728dde4469f517072616a590be610c8af6d616fa77806b4d3ac1176634f78cd29266b4bdae4110ac3cdeb9231";
const publicKey = "0xa19eb5cdd6b3fce15832521908e4f66817e9ea8728dde4469f517072616a590be610c8af6d616fa77806b4d3ac1176634f78cd29266b4bdae4110ac3cdeb9231";
const orderId = await ramp.orderNonce();
const unopenedOrder = await ramp.orders(orderId);
@@ -181,27 +183,26 @@ describe("Ramp", function () {
});
describe("onRamp", function () {
let amount = BigNumber.from(29000000); // $29 (on ramper's perspective)
let maxAmountToPay = BigNumber.from(32000000); // $20 (from on-ramper's perspective)
let minAmountToPay = BigNumber.from(30000000); // $30 (off-ramper's bidding)
let amount = BigNumber.from(9000000); // $9 (on ramper's perspective)
let maxAmountToPay = BigNumber.from(10000000); // $10 (from on-ramper's perspective)
let minAmountToPay = BigNumber.from(10000000); // $10 (off-ramper's bidding)
let claimId = BigNumber.from(0);
let offRamperVenmoId = BigNumber.from("14286706241468003283295067045089601281912688124398815891602745783310727407967");
let orderId=1;
let a = ["0x05f34ff4b36a95c3edd17bb02fb39a2560b282459cd91cd00a0fca2ceed8d9e2", "0x09dec8e8a3b5fc5d32496fa2b412ebe53ed2bda8046f1c47a2ad80abb7c0c70a"];
let b = [["0x0d7de7a45604b118248f16c79a5c78d11d30898898a428cf07b9d7bdf722baba", "0x07a3e20a8861b3fda2c4525b6b484cee4b40822451dc8db2324f1bb515d41df5"],["0x1e92254eccc0f5c3e95f8645557204302341d454c9a8d17f7f0a5bfc05e02808", "0x17c3d119796e3d9b04165ac8823f774d4855a462bfef52456ae28c2b5231f2e7"]];
let c = ["0x003e17fe3fe5e011c72c1e78a760e3b8b0baba5c55e296da5c0561e3a5c36586", "0x0732deb1229407fab505bc7b3313c88c0fb7cf67275267324d42f55fbde06cfa"];
let signals = ["0x1f95fd3aa3a0f764e2eae57d17816218da1f577ce7722e51249e2f28fa5a695f","0x0000000000000000000000000000000000000000000000000000000000003033","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x000000000000000000000000000000000083a043f3f512cb0e9efb506011e359","0x0000000000000000000000000000000000c2e52cefcd800a155366e0207f2563","0x0000000000000000000000000000000000f3576e6387ca2c770760edd72b0fae","0x00000000000000000000000000000000019143a1fc85a71614784b98ff4b16c0","0x00000000000000000000000000000000007bbd0dfb9ef73cf08f4036e24a6b72","0x000000000000000000000000000000000119d3bd704f04dc4f74482cdc239dc7","0x0000000000000000000000000000000001d083a581190a93434412d791fa7fd1","0x000000000000000000000000000000000064350c632569b077ed7b300d3a4051","0x00000000000000000000000000000000000000000000000000a879c82b6c5e0a","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000001"];
let a = ["0x030f041a5bb0e20c7e89129c0ce06b12ebb4dbc57e57687627ebaf487e053c19", "0x02621e3127810cc43c20cb722385f5fa9d4fe71d4c2343884397b714a881e41b"];
let b = [["0x03c2010d7128f692ae23ae9e9404f6345c0e531b7c38b8e3f30f19774d96d098", "0x0864f75fd26a4a2904e0ffba27afd5b1f611e65fd16c16441cacb16c2775c6dd"],["0x0edcd5f61d09b7f75244ef367267258b000693f0d3fdd9f5deb07ce55ca663e8", "0x14ea0b0f58fe04ae99f9ee32096164ef97bf5ec990674968a4eb4f70f9cd40d8"]];
let c = ["0x268de00f442b2c90f899709e7d6f056bd0e1551d28be2458eed119395cf8080d", "0x1a05b29d11ed1a498abb512ea561b381e7b7f328f81e5baf5e9a949878d6cf75"];
let signals = ["0x1f95fd3aa3a0f764e2eae57d17816218da1f577ce7722e51249e2f28fa5a695f","0x0000000000000000000000000000000000000000000000000000000000003033","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000e5ab9ad5b818c501704a57172b2b36","0x0000000000000000000000000000000001281aa2b013864aab62be89d24a4ddb","0x0000000000000000000000000000000000000000000000000000000000003a49","0x000000000000000000000000000000000083a043f3f512cb0e9efb506011e359","0x0000000000000000000000000000000000c2e52cefcd800a155366e0207f2563","0x0000000000000000000000000000000000f3576e6387ca2c770760edd72b0fae","0x00000000000000000000000000000000019143a1fc85a71614784b98ff4b16c0","0x00000000000000000000000000000000007bbd0dfb9ef73cf08f4036e24a6b72","0x000000000000000000000000000000000119d3bd704f04dc4f74482cdc239dc7","0x0000000000000000000000000000000001d083a581190a93434412d791fa7fd1","0x000000000000000000000000000000000064350c632569b077ed7b300d3a4051","0x00000000000000000000000000000000000000000000000000a879c82b6c5e0a","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000001","0x0000000000000000000000000000000000000000000000000000000000000000"];
beforeEach(async function () {
await ramp.connect(onRamper).postOrder(amount, maxAmountToPay, onRamper.address);
await fakeUSDC.connect(offRamper).approve(ramp.address, amount);
await ramp.connect(offRamper).claimOrder(offRamperVenmoId, orderId, "69", minAmountToPay);
await ramp.connect(offRamper).claimOrder(offRamperVenmoId, orderId, "0x69", minAmountToPay);
});
it("sets the order to filled", async function () {
await ramp.connect(onRamper).onRamp(a, b, c, signals, claimId);
await ramp.connect(onRamper).onRamp(a, b, c, signals);
const order = await ramp.orders(orderId)
@@ -212,7 +213,7 @@ describe("Ramp", function () {
const preOnRampBalance = await fakeUSDC.balanceOf(onRamper.address);
const preRampBalance = await fakeUSDC.balanceOf(ramp.address);
await ramp.connect(onRamper).onRamp(a, b, c, signals, claimId);
await ramp.connect(onRamper).onRamp(a, b, c, signals);
const postOnRampBalance = await fakeUSDC.balanceOf(onRamper.address);
const postRampBalance = await fakeUSDC.balanceOf(ramp.address);
@@ -220,6 +221,22 @@ describe("Ramp", function () {
expect(postOnRampBalance).to.equal(preOnRampBalance.add(amount));
expect(postRampBalance).to.equal(preRampBalance.sub(amount));
});
it("sets the nullifier", async function () {
const nullifier = ethers.utils.keccak256(
ethers.utils.defaultAbiCoder.encode(
["uint256", "uint256", "uint256"],
[signals[4], signals[5], signals[6]]
)
);
const nullifiedBefore = await ramp.nullified(nullifier);
await ramp.connect(onRamper).onRamp(a, b, c, signals);
const nullifiedAfter = await ramp.nullified(nullifier);
expect(nullifiedBefore).to.equal(false);
expect(nullifiedAfter).to.equal(true);
});
});
describe.skip("clawback", function () {