Deployer
This following contract is the OpenPeerEscrowsDeployer and is responsible for deploying individual escrow contracts. This contract deploys escrow contracts for native tokens and ERC20 tokens.
Binance Smart Chain
Global settings
arbitrator
: Address of the arbitrator (currently OP staff, DAO later)feeRecipient
: Address to receive the fees_fee
: OP fee (bps) ex: 30 == 0.3%stopped
: Circuit breaker flagimplementation
: Address of the OpenPeerEscrow implementation contractfeeDiscountNFT
: NFT contract for fee discounts
Events
ContractCreated(address _seller, address _deployment)
: Emits when an escrow contract is deployed
Modifiers
stopInEmergency
: Circuit breaker modifier
Functions
constructor()
: Initializes the contract with the given parametersdeploy()
: Deploys a new escrow contract for the msg sendersetArbitrator(address _arbitrator)
: Updates the arbitratorsetFeeRecipient(address payable _feeRecipient)
: Updates the fee recipientsetFee(uint256 fee_)
: Updates the feesetTrustedForwarder(address trustedForwarder)
: Updates the trusted forwarderupdatePartnerFeeBps(address[] calldata _partners, uint256[] calldata _fees)
: Updates the fees of the partners (bps). Cant be more than 1%. Users can pass the 0x address to avoid it.openpeerFee()
: Returns the fee OP will receive from the orders.sellerFee(address _partner)
: Returns the total fee a seller will pay (bps)
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {Clones} from "@openzeppelin/contracts/proxy/Clones.sol";
import {IERC721} from "@openzeppelin/contracts/interfaces/IERC721.sol";
import {OpenPeerEscrow} from "./OpenPeerEscrow.sol";
import {ERC2771Context} from "./libs/ERC2771Context.sol";
import {Ownable} from "./libs/Ownable.sol";
contract OpenPeerEscrowsDeployer is ERC2771Context, Ownable {
mapping(address => address) public sellerContracts;
mapping(address => uint256) public partnerFeeBps;
/***********************
+ Global settings +
***********************/
address public arbitrator;
address payable public feeRecipient;
uint256 private fee;
uint256 public disputeFee;
bool public stopped;
address public implementation;
// NFT contract for fee discounts
address public feeDiscountNFT;
/**********************
+ Events +
***********************/
event ContractCreated(address _seller, address _deployment);
/// @notice Settings
/// @param _arbitrator Address of the arbitrator (currently OP staff)
/// @param _feeRecipient Address to receive the fees
/// @param _fee OP fee (bps) ex: 30 == 0.3%
/// @param _trustedForwarder Forwarder address
/// @param _feeDiscountNFT NFT contract for fee discounts
/// @param _disputeFee Dispute fee
constructor(
address _arbitrator,
address payable _feeRecipient,
uint256 _fee,
address _trustedForwarder,
address _feeDiscountNFT,
uint256 _disputeFee
) ERC2771Context(_trustedForwarder) {
arbitrator = _arbitrator;
feeRecipient = _feeRecipient;
fee = _fee;
feeDiscountNFT = _feeDiscountNFT;
disputeFee = _disputeFee;
implementation = address(new OpenPeerEscrow(_trustedForwarder));
}
/***********************
+ Modifiers +
***********************/
// circuit breaker modifiers
modifier stopInEmergency() {
if (stopped) {
revert("Paused");
} else {
_;
}
}
function deploy() external returns (address) {
address deployment = Clones.clone(implementation);
OpenPeerEscrow(payable(deployment)).initialize(
payable(_msgSender()),
fee,
arbitrator,
feeRecipient,
_trustedForwarder,
feeDiscountNFT,
disputeFee
);
sellerContracts[_msgSender()] = deployment;
emit ContractCreated(_msgSender(), deployment);
return deployment;
}
/***********************
+ Setters +
***********************/
/// @notice Updates the arbitrator
/// @param _arbitrator Address of the arbitrator
function setArbitrator(address _arbitrator) public onlyOwner {
require(_arbitrator != address(0), "Invalid arbitrator");
arbitrator = _arbitrator;
}
/// @notice Updates the fee recipient
/// @param _feeRecipient Address of the arbitrator
function setFeeRecipient(address payable _feeRecipient) public onlyOwner {
require(_feeRecipient != address(0), "Invalid fee recipient");
feeRecipient = _feeRecipient;
}
/// @notice Updates the fee
/// @param _fee fee amount (bps)
function setFee(uint256 _fee) public onlyOwner {
require(_fee <= 100);
fee = _fee;
}
/// @notice Updates the forwarder
/// @param trustedForwarder biconomy forwarder
function setTrustedForwarder(address trustedForwarder) external onlyOwner {
require(trustedForwarder != address(0), "Invalid trust forwarder");
_trustedForwarder = trustedForwarder;
}
/// @notice Updates the implementation
/// @param _implementation Address of the implementation
function setImplementation(
address payable _implementation
) public onlyOwner {
require(_implementation != address(0), "Invalid implementation");
implementation = _implementation;
}
/// @notice Pauses and activate the contract
function toggleContractActive() public onlyOwner {
stopped = !stopped;
}
/// @notice Version recipient
function versionRecipient() external pure returns (string memory) {
return "1.0";
}
/// @notice Updates the NFT contract for fee discounts
function setFeeDiscountNFT(address _feeDiscountNFT) external onlyOwner {
feeDiscountNFT = _feeDiscountNFT;
}
function updatePartnerFeeBps(
address[] calldata _partners,
uint256[] calldata _fees
) external onlyOwner {
require(_partners.length == _fees.length, "Invalid input");
for (uint256 i = 0; i < _partners.length; i++) {
require(_fees[i] <= 100, "Invalid fee bps");
require(_partners[i] != address(0), "Invalid partner address");
partnerFeeBps[_partners[i]] = _fees[i];
}
}
/***********************
+ Getters +
***********************/
function openPeerFee() public view returns (uint256) {
IERC721 discountNFT = IERC721(feeDiscountNFT);
if (
feeDiscountNFT != address(0) &&
discountNFT.balanceOf(_msgSender()) > 0
) {
return 0;
}
return fee;
}
function sellerFee(address _partner) public view returns (uint256) {
return openPeerFee() + partnerFeeBps[_partner];
}
}
Last updated