calc public amount

This commit is contained in:
Alexey 2021-08-16 22:17:07 +03:00
parent 8ab4b33d91
commit 042be187d1
4 changed files with 19 additions and 8 deletions

View File

@ -117,7 +117,7 @@ template Transaction(levels, nIns, nOuts, zeroLeaf) {
} }
// verify amount invariant // verify amount invariant
sumIns === sumOuts + publicAmount; sumIns + publicAmount === sumOuts;
// Check merkle tree update with inserted transaction outputs // Check merkle tree update with inserted transaction outputs
component treeUpdater = TreeUpdater(levels, 1 /* log2(nOuts) */, zeroLeaf); component treeUpdater = TreeUpdater(levels, 1 /* log2(nOuts) */, zeroLeaf);

View File

@ -21,7 +21,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; int256 public constant MAX_EXT_AMOUNT = 2**248;
uint256 public constant MAX_FEE = 2**248; uint256 public constant MAX_FEE = 2**248;
mapping(bytes32 => bool) public nullifierHashes; mapping(bytes32 => bool) public nullifierHashes;
@ -83,11 +83,7 @@ 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 < MAX_FEE, "Invalid fee"); require(_args.publicAmount == calculatePublicAmount(_extData.extAmount, _extData.fee), "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;
@ -117,6 +113,13 @@ contract TornadoPool {
} }
} }
function calculatePublicAmount(int256 _extAmount, uint256 _fee) public pure returns(uint256) {
require(_fee < MAX_FEE, "Invalid fee");
require(_extAmount > -MAX_EXT_AMOUNT && _extAmount < MAX_EXT_AMOUNT, "Invalid ext amount");
int256 publicAmount = _extAmount - int256(_fee);
return (publicAmount >= 0) ? uint256(publicAmount) : FIELD_SIZE - uint256(-publicAmount);
}
/** @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

@ -61,7 +61,7 @@ async function getProof({ inputs, outputs, tree, extAmount, fee, recipient, rela
newRoot: tree.root(), newRoot: tree.root(),
inputNullifier: inputs.map((x) => x.getNullifier()), inputNullifier: inputs.map((x) => x.getNullifier()),
outputCommitment: outputs.map((x) => x.getCommitment()), outputCommitment: outputs.map((x) => x.getCommitment()),
publicAmount: BigNumber.from(fee).sub(extAmount).add(FIELD_SIZE).mod(FIELD_SIZE).toString(), publicAmount: BigNumber.from(extAmount).sub(fee).add(FIELD_SIZE).mod(FIELD_SIZE).toString(),
extDataHash, extDataHash,
// data for 2 transaction inputs // data for 2 transaction inputs

View File

@ -44,6 +44,14 @@ describe('TornadoPool', () => {
expect(result).to.be.deep.equal(data) expect(result).to.be.deep.equal(data)
}) })
it('constants check', async () => {
const maxFee = await tornadoPool.MAX_FEE()
const maxExtAmount = await tornadoPool.MAX_EXT_AMOUNT()
const fieldSize = await tornadoPool.FIELD_SIZE()
expect(maxExtAmount.add(maxFee)).to.be.lt(fieldSize)
})
it('should register and deposit', async function () { it('should register and deposit', async function () {
// Alice deposits into tornado pool // Alice deposits into tornado pool
const aliceDepositAmount = 1e7 const aliceDepositAmount = 1e7