refactor publicAmount

This commit is contained in:
poma 2021-08-16 19:53:18 +03:00
parent 12c90882d1
commit 8ab4b33d91
No known key found for this signature in database
GPG Key ID: BA20CB01FE165657
4 changed files with 25 additions and 30 deletions

View File

@ -9,4 +9,5 @@ yarn test
``` ```
TODO TODO
1. deposit from mainnet to the pool on optimism in one tx 1. deposit from mainnet to the pool on optimism in one tx

View File

@ -22,6 +22,7 @@ interface IVerifier {
contract TornadoPool { contract TornadoPool {
uint256 public constant FIELD_SIZE = 21888242871839275222246405745257275088548364400416034343698204186575808495617; uint256 public constant FIELD_SIZE = 21888242871839275222246405745257275088548364400416034343698204186575808495617;
uint256 public constant MAX_EXT_AMOUNT = 2**248 - 1; uint256 public constant MAX_EXT_AMOUNT = 2**248 - 1;
uint256 public constant MAX_FEE = 2**248;
mapping(bytes32 => bool) public nullifierHashes; mapping(bytes32 => bool) public nullifierHashes;
bytes32 public currentRoot; bytes32 public currentRoot;
@ -31,7 +32,7 @@ contract TornadoPool {
struct ExtData { struct ExtData {
address payable recipient; address payable recipient;
uint256 extAmount; int256 extAmount;
address payable relayer; address payable relayer;
uint256 fee; uint256 fee;
bytes encryptedOutput1; bytes encryptedOutput1;
@ -82,8 +83,11 @@ contract TornadoPool {
require(uint256(_args.extDataHash) == uint256(keccak256(abi.encode(_extData))) % FIELD_SIZE, "Incorrect external data hash"); require(uint256(_args.extDataHash) == uint256(keccak256(abi.encode(_extData))) % FIELD_SIZE, "Incorrect external data hash");
uint256 cachedCommitmentIndex = currentCommitmentIndex; uint256 cachedCommitmentIndex = currentCommitmentIndex;
require(_args.outPathIndices == cachedCommitmentIndex >> 1, "Invalid merkle tree insert position"); require(_args.outPathIndices == cachedCommitmentIndex >> 1, "Invalid merkle tree insert position");
require(_extData.fee < 2**248, "Invalid fee"); require(_extData.fee < MAX_FEE, "Invalid fee");
require((_args.publicAmount + _extData.extAmount) % FIELD_SIZE == _extData.fee % FIELD_SIZE, "Invalid public amount"); require(_extData.extAmount < int256(MAX_EXT_AMOUNT) && _extData.extAmount > -int256(MAX_EXT_AMOUNT), "Invalid ext amount");
int256 _publicAmount = int256(_extData.fee) - _extData.extAmount;
uint256 publicAmount = (_publicAmount >= 0) ? uint256(_publicAmount) : FIELD_SIZE + uint256(_publicAmount);
require(_args.publicAmount == publicAmount, "Invalid public amount");
require(verifyProof(_args), "Invalid transaction proof"); require(verifyProof(_args), "Invalid transaction proof");
currentRoot = _args.newRoot; currentRoot = _args.newRoot;
@ -92,13 +96,12 @@ contract TornadoPool {
nullifierHashes[_args.inputNullifiers[i]] = true; nullifierHashes[_args.inputNullifiers[i]] = true;
} }
int256 extAmount = calculateExternalAmount(_extData.extAmount); if (_extData.extAmount > 0) {
if (extAmount > 0) {
require(msg.value == uint256(_extData.extAmount), "Incorrect amount of ETH sent on deposit"); require(msg.value == uint256(_extData.extAmount), "Incorrect amount of ETH sent on deposit");
} else if (extAmount < 0) { } else if (_extData.extAmount < 0) {
require(msg.value == 0, "Sent ETH amount should be 0 for withdrawal"); require(msg.value == 0, "Sent ETH amount should be 0 for withdrawal");
require(_extData.recipient != address(0), "Can't withdraw to zero address"); require(_extData.recipient != address(0), "Can't withdraw to zero address");
_extData.recipient.transfer(uint256(-extAmount)); _extData.recipient.transfer(uint256(-_extData.extAmount));
} else { } else {
require(msg.value == 0, "Sent ETH amount should be 0 for transaction"); require(msg.value == 0, "Sent ETH amount should be 0 for transaction");
} }
@ -114,18 +117,6 @@ contract TornadoPool {
} }
} }
function calculateExternalAmount(uint256 _extAmount) public pure returns (int256) {
// -MAX_EXT_AMOUNT < extAmount < MAX_EXT_AMOUNT
if (_extAmount < MAX_EXT_AMOUNT) {
return int256(_extAmount);
} else if (_extAmount > FIELD_SIZE - MAX_EXT_AMOUNT) {
// FIELD_SIZE - MAX_EXT_AMOUNT < _extAmount < FIELD_SIZE
return -(int256(FIELD_SIZE) - int256(_extAmount));
} else {
revert("Invalid extAmount value");
}
}
/** @dev whether a note is already spent */ /** @dev whether a note is already spent */
function isSpent(bytes32 _nullifierHash) public view returns (bool) { function isSpent(bytes32 _nullifierHash) public view returns (bool) {
return nullifierHashes[_nullifierHash]; return nullifierHashes[_nullifierHash];

View File

@ -121,10 +121,7 @@ async function prepareTransaction({
.add(outputs.reduce((sum, x) => sum.add(x.amount), BigNumber.from(0))) .add(outputs.reduce((sum, x) => sum.add(x.amount), BigNumber.from(0)))
.sub(inputs.reduce((sum, x) => sum.add(x.amount), BigNumber.from(0))) .sub(inputs.reduce((sum, x) => sum.add(x.amount), BigNumber.from(0)))
const amount = extAmount > 0 ? extAmount : 0 // extAmount will be positive for a deposit, zero for a transact and negative for withdraw const amount = extAmount > 0 ? extAmount : 0
if (extAmount < 0) {
extAmount = FIELD_SIZE.add(extAmount)
}
const { args, extData } = await getProof({ const { args, extData } = await getProof({
inputs, inputs,

View File

@ -18,7 +18,7 @@ function getExtDataHash({ recipient, extAmount, relayer, fee, encryptedOutput1,
const encodedData = abi.encode( const encodedData = abi.encode(
[ [
'tuple(address recipient,uint256 extAmount,address relayer,uint256 fee,bytes encryptedOutput1,bytes encryptedOutput2)', 'tuple(address recipient,int256 extAmount,address relayer,uint256 fee,bytes encryptedOutput1,bytes encryptedOutput2)',
], ],
[ [
{ {
@ -36,12 +36,18 @@ function getExtDataHash({ recipient, extAmount, relayer, fee, encryptedOutput1,
} }
/** BigNumber to hex string of specified length */ /** BigNumber to hex string of specified length */
const toFixedHex = (number, length = 32) => function toFixedHex(number, length = 32) {
let result =
'0x' + '0x' +
(number instanceof Buffer (number instanceof Buffer
? number.toString('hex') ? number.toString('hex')
: BigNumber.from(number).toHexString().slice(2) : BigNumber.from(number).toHexString().replace('0x', '')
).padStart(length * 2, '0') ).padStart(length * 2, '0')
if (result.indexOf('-') > -1) {
result = '-' + result.replace('-', '')
}
return result
}
/** Convert value into buffer of specified byte length */ /** Convert value into buffer of specified byte length */
const toBuffer = (value, length) => const toBuffer = (value, length) =>