mirror of
https://github.com/tornadocash/tornado-nova
synced 2024-02-02 14:53:56 +01:00
113 lines
4.1 KiB
Solidity
113 lines
4.1 KiB
Solidity
// SPDX-License-Identifier: MIT
|
|
// https://tornado.cash
|
|
/*
|
|
* d888888P dP a88888b. dP
|
|
* 88 88 d8' `88 88
|
|
* 88 .d8888b. 88d888b. 88d888b. .d8888b. .d888b88 .d8888b. 88 .d8888b. .d8888b. 88d888b.
|
|
* 88 88' `88 88' `88 88' `88 88' `88 88' `88 88' `88 88 88' `88 Y8ooooo. 88' `88
|
|
* 88 88. .88 88 88 88 88. .88 88. .88 88. .88 dP Y8. .88 88. .88 88 88 88
|
|
* dP `88888P' dP dP dP `88888P8 `88888P8 `88888P' 88 Y88888P' `88888P8 `88888P' dP dP
|
|
* ooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo
|
|
*/
|
|
|
|
pragma solidity ^0.7.0;
|
|
pragma abicoder v2;
|
|
|
|
import "omnibridge/contracts/helpers/WETHOmnibridgeRouter.sol";
|
|
import "@openzeppelin/contracts/math/SafeMath.sol";
|
|
|
|
/// @dev Extension for original WETHOmnibridgeRouter that stores TornadoPool account registrations.
|
|
contract L1Unwrapper is WETHOmnibridgeRouter {
|
|
using SafeMath for uint256;
|
|
|
|
// If this address sets to not zero it receives L1_fee.
|
|
// It can be changed by the multisig.
|
|
// And should implement fee sharing logic:
|
|
// - some part to tx.origin - based on block base fee and can be subsidized
|
|
// - store surplus of ETH for future subsidizions
|
|
address payable public l1FeeReceiver;
|
|
|
|
event PublicKey(address indexed owner, bytes key);
|
|
|
|
struct Account {
|
|
address owner;
|
|
bytes publicKey;
|
|
}
|
|
|
|
constructor(
|
|
IOmnibridge _bridge,
|
|
IWETH _weth,
|
|
address _owner
|
|
) WETHOmnibridgeRouter(_bridge, _weth, _owner) {}
|
|
|
|
/** @dev Registers provided public key and its owner in pool
|
|
* @param _account pair of address and key
|
|
*/
|
|
function register(Account memory _account) public {
|
|
require(_account.owner == msg.sender, "only owner can be registered");
|
|
_register(_account);
|
|
}
|
|
|
|
/**
|
|
* @dev Wraps native assets and relays wrapped ERC20 tokens to the other chain.
|
|
* It also calls receiver on other side with the _data provided.
|
|
* @param _receiver bridged assets receiver on the other side of the bridge.
|
|
* @param _data data for the call of receiver on other side.
|
|
* @param _account tornadoPool account data
|
|
*/
|
|
function wrapAndRelayTokens(
|
|
address _receiver,
|
|
bytes memory _data,
|
|
Account memory _account
|
|
) public payable {
|
|
WETH.deposit{ value: msg.value }();
|
|
bridge.relayTokensAndCall(address(WETH), _receiver, msg.value, _data);
|
|
|
|
if (_account.owner == msg.sender) {
|
|
_register(_account);
|
|
}
|
|
}
|
|
|
|
function _register(Account memory _account) internal {
|
|
emit PublicKey(_account.owner, _account.publicKey);
|
|
}
|
|
|
|
/**
|
|
* @dev Bridged callback function used for unwrapping received tokens.
|
|
* Can only be called by the associated Omnibridge contract.
|
|
* @param _token bridged token contract address, should be WETH.
|
|
* @param _value amount of bridged/received tokens.
|
|
* @param _data extra data passed alongside with relayTokensAndCall on the other side of the bridge.
|
|
* Should contain coins receiver address and L1 executer fee amount.
|
|
*/
|
|
function onTokenBridged(
|
|
address _token,
|
|
uint256 _value,
|
|
bytes memory _data
|
|
) external override {
|
|
require(_token == address(WETH), "only WETH token");
|
|
require(msg.sender == address(bridge), "only from bridge address");
|
|
require(_data.length == 64, "incorrect data length");
|
|
|
|
WETH.withdraw(_value);
|
|
|
|
(address payable receipient, uint256 l1Fee) = abi.decode(_data, (address, uint256));
|
|
|
|
AddressHelper.safeSendValue(receipient, _value.sub(l1Fee));
|
|
|
|
if (l1Fee > 0) {
|
|
address payable l1FeeTo = l1FeeReceiver != payable(address(0)) ? l1FeeReceiver : payable(tx.origin);
|
|
AddressHelper.safeSendValue(l1FeeTo, l1Fee);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @dev Sets l1FeeReceiver address.
|
|
* Only contract owner can call this method.
|
|
* @param _receiver address of new L1FeeReceiver, address(0) for native tx.origin receiver.
|
|
*/
|
|
function setL1FeeReceiver(address payable _receiver) external onlyOwner {
|
|
l1FeeReceiver = _receiver;
|
|
}
|
|
}
|