mirror of
https://github.com/zkp2p/zkp2p-poc.git
synced 2026-01-09 13:48:06 -05:00
[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:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
@@ -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****"
|
||||
|
||||
3
circuit/server-scripts/generate_contract.sh
Normal file
3
circuit/server-scripts/generate_contract.sh
Normal file
@@ -0,0 +1,3 @@
|
||||
# Turn the verifier into a smart contract
|
||||
cd circuit
|
||||
$SNARKJS_PATH zkey export solidityverifier circuit.zkey ../contracts/Verifier.sol
|
||||
@@ -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
|
||||
|
||||
@@ -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, "!")
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.12;
|
||||
|
||||
import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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]);
|
||||
|
||||
@@ -34,5 +34,13 @@ module.exports = {
|
||||
paths: {
|
||||
artifacts: "./artifacts",
|
||||
},
|
||||
solidity: "0.8.12",
|
||||
solidity: {
|
||||
version: "0.8.12",
|
||||
settings: {
|
||||
optimizer: {
|
||||
enabled: true,
|
||||
runs: 200
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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": "",
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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 () {
|
||||
|
||||
Reference in New Issue
Block a user