编译器
0.8.21+commit.d9974bed
文件 1 的 11:Address.sol
pragma solidity ^0.8.1;
library Address {
function isContract(address account) internal view returns (bool) {
return account.code.length > 0;
}
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
(bool success, ) = recipient.call{value: amount}("");
require(success, "Address: unable to send value, recipient may have reverted");
}
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, "Address: low-level call failed");
}
function functionCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
function functionCallWithValue(
address target,
bytes memory data,
uint256 value,
string memory errorMessage
) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
function functionStaticCall(
address target,
bytes memory data,
string memory errorMessage
) internal view returns (bytes memory) {
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
function functionDelegateCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
function verifyCallResultFromTarget(
address target,
bool success,
bytes memory returndata,
string memory errorMessage
) internal view returns (bytes memory) {
if (success) {
if (returndata.length == 0) {
require(isContract(target), "Address: call to non-contract");
}
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
function verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) internal pure returns (bytes memory) {
if (success) {
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
function _revert(bytes memory returndata, string memory errorMessage) private pure {
if (returndata.length > 0) {
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
文件 2 的 11:Context.sol
pragma solidity ^0.8.0;
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}
文件 3 的 11:IERC1155Receiver.sol
pragma solidity ^0.8.0;
import "../../utils/introspection/IERC165.sol";
interface IERC1155Receiver is IERC165 {
function onERC1155Received(
address operator,
address from,
uint256 id,
uint256 value,
bytes calldata data
) external returns (bytes4);
function onERC1155BatchReceived(
address operator,
address from,
uint256[] calldata ids,
uint256[] calldata values,
bytes calldata data
) external returns (bytes4);
}
文件 4 的 11:IERC165.sol
pragma solidity ^0.8.0;
interface IERC165 {
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
文件 5 的 11:IERC20.sol
pragma solidity ^0.8.0;
interface IERC20 {
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(address to, uint256 amount) external returns (bool);
function allowance(address owner, address spender) external view returns (uint256);
function approve(address spender, uint256 amount) external returns (bool);
function transferFrom(address from, address to, uint256 amount) external returns (bool);
}
文件 6 的 11:IERC20Permit.sol
pragma solidity ^0.8.0;
interface IERC20Permit {
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external;
function nonces(address owner) external view returns (uint256);
function DOMAIN_SEPARATOR() external view returns (bytes32);
}
文件 7 的 11:Ownable.sol
pragma solidity ^0.8.0;
import "../utils/Context.sol";
abstract contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
constructor() {
_transferOwnership(_msgSender());
}
modifier onlyOwner() {
_checkOwner();
_;
}
function owner() public view virtual returns (address) {
return _owner;
}
function _checkOwner() internal view virtual {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
}
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
_transferOwnership(newOwner);
}
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
文件 8 的 11:Pausable.sol
pragma solidity ^0.8.0;
import "../utils/Context.sol";
abstract contract Pausable is Context {
event Paused(address account);
event Unpaused(address account);
bool private _paused;
constructor() {
_paused = false;
}
modifier whenNotPaused() {
_requireNotPaused();
_;
}
modifier whenPaused() {
_requirePaused();
_;
}
function paused() public view virtual returns (bool) {
return _paused;
}
function _requireNotPaused() internal view virtual {
require(!paused(), "Pausable: paused");
}
function _requirePaused() internal view virtual {
require(paused(), "Pausable: not paused");
}
function _pause() internal virtual whenNotPaused {
_paused = true;
emit Paused(_msgSender());
}
function _unpause() internal virtual whenPaused {
_paused = false;
emit Unpaused(_msgSender());
}
}
文件 9 的 11:ReentrancyGuard.sol
pragma solidity ^0.8.0;
abstract contract ReentrancyGuard {
uint256 private constant _NOT_ENTERED = 1;
uint256 private constant _ENTERED = 2;
uint256 private _status;
constructor() {
_status = _NOT_ENTERED;
}
modifier nonReentrant() {
_nonReentrantBefore();
_;
_nonReentrantAfter();
}
function _nonReentrantBefore() private {
require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
_status = _ENTERED;
}
function _nonReentrantAfter() private {
_status = _NOT_ENTERED;
}
function _reentrancyGuardEntered() internal view returns (bool) {
return _status == _ENTERED;
}
}
文件 10 的 11:SafeERC20.sol
pragma solidity ^0.8.0;
import "../IERC20.sol";
import "../extensions/IERC20Permit.sol";
import "../../../utils/Address.sol";
library SafeERC20 {
using Address for address;
function safeTransfer(IERC20 token, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
}
function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
}
function safeApprove(IERC20 token, address spender, uint256 value) internal {
require(
(value == 0) || (token.allowance(address(this), spender) == 0),
"SafeERC20: approve from non-zero to non-zero allowance"
);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
}
function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 oldAllowance = token.allowance(address(this), spender);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));
}
function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {
unchecked {
uint256 oldAllowance = token.allowance(address(this), spender);
require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));
}
}
function forceApprove(IERC20 token, address spender, uint256 value) internal {
bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);
if (!_callOptionalReturnBool(token, approvalCall)) {
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));
_callOptionalReturn(token, approvalCall);
}
}
function safePermit(
IERC20Permit token,
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) internal {
uint256 nonceBefore = token.nonces(owner);
token.permit(owner, spender, value, deadline, v, r, s);
uint256 nonceAfter = token.nonces(owner);
require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed");
}
function _callOptionalReturn(IERC20 token, bytes memory data) private {
bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
require(returndata.length == 0 || abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
}
function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {
(bool success, bytes memory returndata) = address(token).call(data);
return
success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));
}
}
文件 11 的 11:TraitSwapping.sol
pragma solidity ^0.8.21;
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/security/Pausable.sol";
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol";
interface IRVM {
function burn(address account, uint256 id, uint256 value) external;
function isApprovedForAll(address account, address operator) external view returns (bool);
}
interface IALTS {
function ownerOf(uint256 tokenId) external view returns (address);
}
contract TraitSwapping is Ownable, Pausable, ReentrancyGuard, IERC1155Receiver {
using SafeERC20 for IERC20;
IERC20 public immutable APE;
IRVM public immutable RVM;
IALTS public immutable ALTS;
IERC20 public immutable WETH;
enum Currency {
ETH,
WETH,
APE,
RVM
}
enum OrderStatus {
UNSET,
PENDING,
ACCEPTED,
CANCELED
}
struct Order {
address buyer;
uint96 amount;
address seller;
uint32 expiresAt;
uint24 id;
uint16 buyerAlt;
uint16 sellerAlt;
OrderStatus status;
}
struct Transfer {
address buyer;
uint16[3] buyerAlts;
uint16[3] sellerAlts;
address seller;
uint72 amount;
uint24 id;
}
struct Exchange {
uint72 rateApe;
uint56 rateEth;
uint56 minFee;
uint56 minOrder;
uint8 rateRvm;
uint8 fee;
}
Exchange public exchange;
address payable public receiver;
address public permittedOperator;
bool public pointsTransfers = false;
uint32 public expiryPeriod;
uint24 public totalOrders = 0;
uint24 public totalTransfers = 0;
mapping(address => uint256) public points;
mapping(uint56 => Order) public orders;
mapping(uint96 => Transfer) private transfers;
event PointsPurchase(
address indexed user,
Currency indexed currency,
uint256 value,
uint256 indexed points,
uint256 currentPointsBalance
);
event TransferPoints(address indexed sender, address indexed receiver, uint256 amount);
event TransferWETH(uint96 indexed id, address indexed buyer, address indexed seller, uint256 amount, uint256 fee);
event OrderCreated(
uint56 indexed orderId,
address indexed buyer,
address indexed seller,
uint256 amount,
uint32 expiresAt
);
event OrderFulfilled(uint56 indexed orderId);
event OrderCanceled(uint56 indexed orderId, address indexed buyer, address indexed seller, uint256 amount);
constructor(
uint56 _rateEth,
uint72 _rateApe,
uint8 _rateRvm,
uint56 _minFee,
uint56 _minOrder,
uint8 _fee,
uint32 _expiryPeriod,
address _ape,
address _rvm,
address _weth,
address _alts,
address _permittedOperator,
address payable _receiver
) {
exchange.rateEth = _rateEth;
exchange.rateApe = _rateApe;
exchange.rateRvm = _rateRvm;
exchange.minFee = _minFee;
exchange.minOrder = _minOrder;
exchange.fee = _fee;
expiryPeriod = _expiryPeriod;
APE = IERC20(_ape);
RVM = IRVM(_rvm);
WETH = IERC20(_weth);
ALTS = IALTS(_alts);
permittedOperator = _permittedOperator;
receiver = _receiver;
}
modifier onlyPermittedOperator() {
require(msg.sender == permittedOperator || msg.sender == owner(), "Not a permitted operator");
_;
}
function exchangeETH() external payable nonReentrant whenNotPaused {
require(msg.value > 0, "Amount cannot be 0");
require(msg.value % exchange.rateEth == 0, "Invalid ETH amount");
uint256 pointsToReceive = msg.value / exchange.rateEth;
points[msg.sender] += pointsToReceive;
(bool sent, ) = receiver.call{value: msg.value}("");
require(sent, "Failed to send ETH");
emit PointsPurchase(msg.sender, Currency.ETH, msg.value, pointsToReceive, points[msg.sender]);
}
function exchangeWETH(uint256 amount) external nonReentrant whenNotPaused {
require(amount > 0, "Amount cannot be 0");
require(amount % exchange.rateEth == 0, "Invalid WETH amount");
uint256 pointsToReceive = amount / exchange.rateEth;
points[msg.sender] += pointsToReceive;
WETH.safeTransferFrom(msg.sender, receiver, amount);
emit PointsPurchase(msg.sender, Currency.WETH, amount, pointsToReceive, points[msg.sender]);
}
function exchangeAPE(uint256 amount) external nonReentrant whenNotPaused {
require(amount > 0, "Amount cannot be 0");
require(amount % exchange.rateApe == 0, "Invalid APE amount");
uint256 pointsToReceive = amount / exchange.rateApe;
points[msg.sender] += pointsToReceive;
APE.safeTransferFrom(msg.sender, receiver, amount);
emit PointsPurchase(msg.sender, Currency.APE, amount, pointsToReceive, points[msg.sender]);
}
function exchangeRVM(uint256 amount) external nonReentrant whenNotPaused {
require(amount > 0, "Amount cannot be 0");
require(amount % exchange.rateRvm == 0, "Invalid RVM amount");
uint256 pointsToReceive = amount / exchange.rateRvm;
points[msg.sender] += pointsToReceive;
RVM.burn(msg.sender, 0, amount);
emit PointsPurchase(msg.sender, Currency.RVM, amount, pointsToReceive, points[msg.sender]);
}
function executeWETHOrder(Transfer memory transfer) external nonReentrant whenNotPaused {
require(transfer.buyer == msg.sender, "Buyer must create own order");
require(transfer.amount >= exchange.minOrder, "Transfer amount is below minimum");
require(validateAltsOwnership(transfer.buyerAlts, msg.sender), "Buyer: no valid ALT ID");
require(validateAltsOwnership(transfer.sellerAlts, transfer.seller), "Seller: no valid ALT ID");
unchecked {
uint256 minFee = exchange.minFee;
uint256 calculatedFee = (transfer.amount * exchange.fee) / 100;
uint256 feeAmount = calculatedFee < minFee ? minFee : calculatedFee;
totalTransfers++;
transfer.id = totalTransfers;
transfers[transfer.id] = transfer;
address buyer = transfer.buyer;
WETH.safeTransferFrom(buyer, receiver, feeAmount);
WETH.safeTransferFrom(buyer, transfer.seller, transfer.amount);
emit TransferWETH(transfer.id, transfer.buyer, transfer.seller, transfer.amount, feeAmount);
}
}
function createOrder(Order memory order) external nonReentrant whenNotPaused {
require(order.buyer == msg.sender, "Buyer must create their own order");
require(order.buyerAlt >= 1 && order.buyerAlt <= 30000, "Invalid buyer ALT ID");
require(order.sellerAlt >= 1 && order.sellerAlt <= 30000, "Invalid seller ALT ID");
require(order.amount >= exchange.minOrder, "Order amount is below minimum");
require(ALTS.ownerOf(order.buyerAlt) == msg.sender, "Buyer does not own the specified ALT");
require(ALTS.ownerOf(order.sellerAlt) == order.seller, "Seller does not own the specified ALT");
unchecked {
uint256 minFee = exchange.minFee;
uint256 calculatedFee = (order.amount * exchange.fee) / 100;
uint256 feeAmount = calculatedFee < minFee ? minFee : calculatedFee;
require(
WETH.allowance(msg.sender, address(this)) >= order.amount + feeAmount,
"Insufficient WETH allowance"
);
totalOrders++;
}
order.id = totalOrders;
order.status = OrderStatus.PENDING;
order.expiresAt = uint32(block.timestamp + expiryPeriod);
orders[order.id] = order;
emit OrderCreated(order.id, order.buyer, order.seller, order.amount, order.expiresAt);
}
function cancelOrder(uint56 id) external nonReentrant whenNotPaused {
Order storage order = orders[id];
OrderStatus status = order.status;
require(status != OrderStatus.UNSET, "Order does not exist");
require(status == OrderStatus.PENDING, "Order is not pending");
address buyer = order.buyer;
require(
buyer == msg.sender || permittedOperator == msg.sender || owner() == msg.sender,
"Not the buyer of this order"
);
order.status = OrderStatus.CANCELED;
emit OrderCanceled(id, buyer, order.seller, order.amount);
}
function fulfillOrder(uint56 id) external onlyPermittedOperator {
Order storage order = orders[id];
require(order.status == OrderStatus.PENDING, "Order not eligible for fulfillment");
if (block.timestamp > order.expiresAt) {
revert("Expired");
}
unchecked {
uint256 orderAmount = order.amount;
uint256 feeAmount = (orderAmount * exchange.fee) / 100;
if (feeAmount < exchange.minFee) {
feeAmount = exchange.minFee;
}
address buyer = order.buyer;
WETH.safeTransferFrom(buyer, receiver, feeAmount);
WETH.safeTransferFrom(buyer, order.seller, orderAmount);
}
order.status = OrderStatus.ACCEPTED;
emit OrderFulfilled(id);
}
function transferPoints(address to, uint256 amount) external nonReentrant whenNotPaused {
require(pointsTransfers, "Transfers of points are disabled");
require(to != address(0), "Cannot send to zero address");
require(points[msg.sender] >= amount, "Insufficient points balance");
points[msg.sender] -= amount;
points[to] += amount;
emit TransferPoints(msg.sender, to, amount);
}
function setPoints(address[] calldata users, uint256[] calldata balances) external onlyPermittedOperator {
require(users.length == balances.length, "Mismatched arrays");
unchecked {
for (uint256 i = 0; i < users.length; i++) {
points[users[i]] = balances[i];
}
}
}
function adjustPoints(address[] calldata users, int256[] calldata adjustments) external onlyPermittedOperator {
require(users.length == adjustments.length, "Mismatched arrays");
unchecked {
for (uint256 i = 0; i < users.length; i++) {
if (adjustments[i] > 0) {
points[users[i]] += uint256(adjustments[i]);
} else {
require(points[users[i]] >= uint256(-adjustments[i]), "Cannot decrease below zero");
points[users[i]] -= uint256(-adjustments[i]);
}
}
}
}
function setReceiver(address payable _receiver) external onlyOwner {
receiver = _receiver;
}
function setExpiryPeriod(uint32 period) external onlyOwner {
expiryPeriod = period;
}
function setExchange(
uint56 eth,
uint72 ape,
uint8 rvm,
uint8 fee,
uint56 minFee,
uint56 minOrder
) external onlyOwner {
exchange.rateApe = ape;
exchange.rateEth = eth;
exchange.minFee = fee;
exchange.minOrder = minOrder;
exchange.rateRvm = rvm;
exchange.fee = fee;
}
function setPermittedOperator(address _operator) external onlyOwner {
require(_operator != address(0), "Operator address cannot be null");
permittedOperator = _operator;
}
function removePermittedOperator() external onlyOwner {
permittedOperator = address(0);
}
function getAllowances(address user) external view returns (uint256[] memory) {
uint256[] memory allowances = new uint256[](3);
allowances[0] = WETH.allowance(user, address(this));
allowances[1] = APE.allowance(user, address(this));
allowances[2] = RVM.isApprovedForAll(user, address(this)) ? 1 : 0;
return allowances;
}
function getOrdersByUser(
address user,
uint56 start,
uint56 end,
bool isSeller
) external view returns (uint56[] memory) {
require(start <= end, "Invalid range");
uint56[] memory orderRange = new uint56[](end - start + 1);
uint256 count = 0;
unchecked {
for (uint56 i = start; i <= end; i++) {
bool isUserOrder = (isSeller && orders[i].seller == user) || (!isSeller && orders[i].buyer == user);
if (isUserOrder && orders[i].status != OrderStatus.UNSET) {
orderRange[count++] = i;
}
}
}
uint56[] memory result = new uint56[](count);
unchecked {
for (uint256 j = 0; j < count; j++) {
result[j] = orderRange[j];
}
}
return result;
}
function getTransfer(
uint96 transferId
) public view returns (address, uint16[3] memory, uint16[3] memory, address, uint96, uint256) {
Transfer storage t = transfers[transferId];
return (t.buyer, t.buyerAlts, t.sellerAlts, t.seller, t.id, t.amount);
}
function drainETH() external onlyOwner {
owner().call{value: address(this).balance}("");
}
function drainWETH() external onlyOwner {
WETH.transfer(owner(), WETH.balanceOf(address(this)));
}
function drainAPE() external onlyOwner {
APE.transfer(owner(), APE.balanceOf(address(this)));
}
function enableTransfers() external onlyOwner {
pointsTransfers = true;
}
function disableTransfers() external onlyOwner {
pointsTransfers = false;
}
function pause() external onlyPermittedOperator {
_pause();
}
function unpause() external onlyPermittedOperator {
_unpause();
}
function onERC1155Received(
address operator,
address from,
uint256 id,
uint256 value,
bytes calldata data
) external override returns (bytes4) {
require(address(RVM) == msg.sender, "Only RVM tokens accepted");
require(id == 0, "Only RVM tokenId 0 accepted");
uint256 pointsToReceive = value / exchange.rateRvm;
points[from] += pointsToReceive;
emit PointsPurchase(from, Currency.RVM, value, pointsToReceive, points[from]);
RVM.burn(address(this), id, value);
return this.onERC1155Received.selector;
}
function onERC1155BatchReceived(
address operator,
address from,
uint256[] calldata ids,
uint256[] calldata values,
bytes calldata data
) external override returns (bytes4) {
revert("Not supported");
}
function supportsInterface(bytes4 interfaceId) external pure override returns (bool) {
return interfaceId == type(IERC1155Receiver).interfaceId;
}
function validateAltsOwnership(uint16[3] memory tokenIds, address owner) internal view returns (bool) {
bool validAlt = false;
for (uint i = 0; i < 3; i++) {
if (tokenIds[i] != 0) {
validAlt = true;
require(ALTS.ownerOf(tokenIds[i]) == owner, "ALT ownership mismatch");
}
}
return validAlt;
}
}
{
"compilationTarget": {
"contracts/TraitSwapping.sol": "TraitSwapping"
},
"evmVersion": "paris",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": [],
"viaIR": true
}
[{"inputs":[{"internalType":"uint56","name":"_rateEth","type":"uint56"},{"internalType":"uint72","name":"_rateApe","type":"uint72"},{"internalType":"uint8","name":"_rateRvm","type":"uint8"},{"internalType":"uint56","name":"_minFee","type":"uint56"},{"internalType":"uint56","name":"_minOrder","type":"uint56"},{"internalType":"uint8","name":"_fee","type":"uint8"},{"internalType":"uint32","name":"_expiryPeriod","type":"uint32"},{"internalType":"address","name":"_ape","type":"address"},{"internalType":"address","name":"_rvm","type":"address"},{"internalType":"address","name":"_weth","type":"address"},{"internalType":"address","name":"_alts","type":"address"},{"internalType":"address","name":"_permittedOperator","type":"address"},{"internalType":"address payable","name":"_receiver","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint56","name":"orderId","type":"uint56"},{"indexed":true,"internalType":"address","name":"buyer","type":"address"},{"indexed":true,"internalType":"address","name":"seller","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"OrderCanceled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint56","name":"orderId","type":"uint56"},{"indexed":true,"internalType":"address","name":"buyer","type":"address"},{"indexed":true,"internalType":"address","name":"seller","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint32","name":"expiresAt","type":"uint32"}],"name":"OrderCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint56","name":"orderId","type":"uint56"}],"name":"OrderFulfilled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"enum TraitSwapping.Currency","name":"currency","type":"uint8"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"points","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"currentPointsBalance","type":"uint256"}],"name":"PointsPurchase","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"address","name":"receiver","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"TransferPoints","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint96","name":"id","type":"uint96"},{"indexed":true,"internalType":"address","name":"buyer","type":"address"},{"indexed":true,"internalType":"address","name":"seller","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"fee","type":"uint256"}],"name":"TransferWETH","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"inputs":[],"name":"ALTS","outputs":[{"internalType":"contract IALTS","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"APE","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"RVM","outputs":[{"internalType":"contract IRVM","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"WETH","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"users","type":"address[]"},{"internalType":"int256[]","name":"adjustments","type":"int256[]"}],"name":"adjustPoints","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint56","name":"id","type":"uint56"}],"name":"cancelOrder","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"buyer","type":"address"},{"internalType":"uint96","name":"amount","type":"uint96"},{"internalType":"address","name":"seller","type":"address"},{"internalType":"uint32","name":"expiresAt","type":"uint32"},{"internalType":"uint24","name":"id","type":"uint24"},{"internalType":"uint16","name":"buyerAlt","type":"uint16"},{"internalType":"uint16","name":"sellerAlt","type":"uint16"},{"internalType":"enum TraitSwapping.OrderStatus","name":"status","type":"uint8"}],"internalType":"struct TraitSwapping.Order","name":"order","type":"tuple"}],"name":"createOrder","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"disableTransfers","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"drainAPE","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"drainETH","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"drainWETH","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"enableTransfers","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"exchange","outputs":[{"internalType":"uint72","name":"rateApe","type":"uint72"},{"internalType":"uint56","name":"rateEth","type":"uint56"},{"internalType":"uint56","name":"minFee","type":"uint56"},{"internalType":"uint56","name":"minOrder","type":"uint56"},{"internalType":"uint8","name":"rateRvm","type":"uint8"},{"internalType":"uint8","name":"fee","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"exchangeAPE","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"exchangeETH","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"exchangeRVM","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"exchangeWETH","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"buyer","type":"address"},{"internalType":"uint16[3]","name":"buyerAlts","type":"uint16[3]"},{"internalType":"uint16[3]","name":"sellerAlts","type":"uint16[3]"},{"internalType":"address","name":"seller","type":"address"},{"internalType":"uint72","name":"amount","type":"uint72"},{"internalType":"uint24","name":"id","type":"uint24"}],"internalType":"struct TraitSwapping.Transfer","name":"transfer","type":"tuple"}],"name":"executeWETHOrder","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"expiryPeriod","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint56","name":"id","type":"uint56"}],"name":"fulfillOrder","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"getAllowances","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"uint56","name":"start","type":"uint56"},{"internalType":"uint56","name":"end","type":"uint56"},{"internalType":"bool","name":"isSeller","type":"bool"}],"name":"getOrdersByUser","outputs":[{"internalType":"uint56[]","name":"","type":"uint56[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint96","name":"transferId","type":"uint96"}],"name":"getTransfer","outputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint16[3]","name":"","type":"uint16[3]"},{"internalType":"uint16[3]","name":"","type":"uint16[3]"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint96","name":"","type":"uint96"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"address","name":"from","type":"address"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"uint256[]","name":"values","type":"uint256[]"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"onERC1155BatchReceived","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"address","name":"from","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"onERC1155Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint56","name":"","type":"uint56"}],"name":"orders","outputs":[{"internalType":"address","name":"buyer","type":"address"},{"internalType":"uint96","name":"amount","type":"uint96"},{"internalType":"address","name":"seller","type":"address"},{"internalType":"uint32","name":"expiresAt","type":"uint32"},{"internalType":"uint24","name":"id","type":"uint24"},{"internalType":"uint16","name":"buyerAlt","type":"uint16"},{"internalType":"uint16","name":"sellerAlt","type":"uint16"},{"internalType":"enum TraitSwapping.OrderStatus","name":"status","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"permittedOperator","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"points","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pointsTransfers","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"receiver","outputs":[{"internalType":"address payable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"removePermittedOperator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint56","name":"eth","type":"uint56"},{"internalType":"uint72","name":"ape","type":"uint72"},{"internalType":"uint8","name":"rvm","type":"uint8"},{"internalType":"uint8","name":"fee","type":"uint8"},{"internalType":"uint56","name":"minFee","type":"uint56"},{"internalType":"uint56","name":"minOrder","type":"uint56"}],"name":"setExchange","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"period","type":"uint32"}],"name":"setExpiryPeriod","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_operator","type":"address"}],"name":"setPermittedOperator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"users","type":"address[]"},{"internalType":"uint256[]","name":"balances","type":"uint256[]"}],"name":"setPoints","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address payable","name":"_receiver","type":"address"}],"name":"setReceiver","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"totalOrders","outputs":[{"internalType":"uint24","name":"","type":"uint24"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalTransfers","outputs":[{"internalType":"uint24","name":"","type":"uint24"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferPoints","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"}]