// SPDX-License-Identifier: MIT
pragma solidity =0.8.20;
import "@openzeppelin/contracts/access/Ownable.sol";
import "./AbstractDAO.sol";
contract Bridge is AbstractDAO {
event Unwrapped(
address indexed receiver,
uint256 indexed value,
uint256 indexed nonce
);
event FundsReceived(
address indexed recipient,
uint256 indexed value,
uint256 indexed nonce
);
address public _feeRecipient;
mapping(uint256 => bool) private _withdrawalNonces;
uint256 private _feeIn;
uint256 private _feeOut;
uint256 private _nonce;
bool internal locked;
constructor(
uint256 feeIn,
uint256 feeOut,
uint256 thresholdLevel
) Ownable(msg.sender) {
_feeIn = feeIn;
_feeOut = feeOut;
_thresholdLevel = thresholdLevel;
_threshold = thresholdLevel;
_nonce = 0;
_queueOrder = 1;
_votesSent = 0;
_votingInProgress = 0;
_bps = 6666;
_requiredVoteThreshold = 2 * _bps;
_authorizedAddressesCount = 2;
_feeRecipient = owner();
_operator = owner();
}
modifier nonReentrant() {
Erequire(!locked, "cannot reenter");
locked = true;
_;
locked = false;
}
receive() external payable {
deposit(msg.sender);
}
function feeUnwrap() external view returns (uint256) {
return _feeOut;
}
function feeWrap() external view returns (uint256) {
return _feeIn;
}
function deposit(address onBehalf) public payable EnonReentrant {
require(
msg.value > _feeIn,
"Cannot process value lower or equal to fee"
);
address feeRecipient = payable(_feeRecipient);
(bool sent,) = feeRecipient.call{value: _feeIn}("");
Erequire(sent, "Failed to process fee");
emit FundsReceived(onBehalf, msg.value - _feeIn, _nonce++);
}
function setFees(uint256 authorizedIndex, uint256 newFeeIn, uint256 newFeeOut) external {
require(
msg.sender == _authorizedAddresses[authorizedIndex],
"Must be sent from authorized sender"
);
_feeIn = newFeeIn;
_feeOut = newFeeOut;
}
function setFeeRecipient(uint256 authorizedIndex, address __feeRecipient) external {
require(
__feeRecipient != address(0),
"Must not be null address"
);
require(
msg.sender == _authorizedAddresses[authorizedIndex],
"Must be sent from authorized sender"
);
require(
_feeRecipient != __feeRecipient,
"This withdrawer is already set"
);
_feeRecipient = __feeRecipient;
}
function withdraw(
address recipient,
uint256 value,
uint256 burnNonce
) external EnonReentrant {
require(!_withdrawalNonces[burnNonce], "Nonce already used");
require(
msg.sender == _operator,
"Must be sent from operator address"
);
require(value > _feeOut, "Cannot process value lower or equal to fee");
require(_threshold >= value, "Value exceeds the threshold");
_withdrawalNonces[burnNonce] = true;
address feeRecipient = payable(_feeRecipient);
_threshold -= value;
(bool sent,) = feeRecipient.call{value: _feeOut}("");
Erequire(sent, "Failed to process fee");
(sent,) = recipient.call{value: value - _feeOut}("");
Erequire(sent, "Failed to process withdrawal");
emit Unwrapped(recipient, value, burnNonce);
}
}
|