simple-tornado
simple-tornado copied to clipboard
withdraw is hackable!
I think my version is hackable because the publicSignal root in parameters of verifyProof may be different from the root in parameters of withdraw.
function withdraw(
uint256[2] memory a,
uint256[2][2] memory b,
uint256[2] memory c,
uint256[1] memory input,
bytes32 _root,
bytes32 _nullifierHash,
address payable _recipient,
address payable _relayer,
uint256 _fee,
uint256 _refund
) external payable nonReentrant {
require(_fee <= denomination, "Fee exceeds transfer value");
require(!nullifierHashes[_nullifierHash], "The note has been already spent");
require(isKnownRoot(_root), "Cannot find your merkle root");
require(verifier.verifyProof(a, b, c, input), "Invalid withdraw proof");
...
In tornado-core, function verifyProof divides proof and publicSignals, and it check the publicSignal root is the same as the one in the parameters of withdraw.
function withdraw(bytes calldata _proof, bytes32 _root, bytes32 _nullifierHash, address payable _recipient, address payable _relayer, uint256 _fee, uint256 _refund) external payable nonReentrant {
require(_fee <= denomination, "Fee exceeds transfer value");
require(!nullifierHashes[_nullifierHash], "The note has been already spent");
require(isKnownRoot(_root), "Cannot find your merkle root"); // Make sure to use a recent one
require(verifier.verifyProof(_proof, [uint256(_root), uint256(_nullifierHash), uint256(_recipient), uint256(_relayer), _fee, _refund]), "Invalid withdraw proof");
nullifierHashes[_nullifierHash] = true;
_processWithdraw(_recipient, _relayer, _fee, _refund);
emit Withdrawal(_recipient, _nullifierHash, _relayer, _fee);
}
为什么没有更新你的代码呢?