编译器
0.8.17+commit.8df45f5f
文件 1 的 16: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 functionCall(target, data, "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");
require(isContract(target), "Address: call to non-contract");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResult(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) {
require(isContract(target), "Address: static call to non-contract");
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResult(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) {
require(isContract(target), "Address: delegate call to non-contract");
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResult(success, returndata, errorMessage);
}
function verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) internal pure returns (bytes memory) {
if (success) {
return returndata;
} else {
if (returndata.length > 0) {
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
}
文件 2 的 16:Deal.sol
pragma solidity ^0.8.17;
import './DealPointRef.sol';
struct Deal {
uint256 state;
address owner1;
address owner2;
uint256 pointsCount;
}
文件 3 的 16:DealPointData.sol
pragma solidity ^0.8.17;
struct DealPointData {
address controller;
uint256 id;
uint256 dealPointTypeId;
uint256 dealId;
address from;
address to;
address owner;
uint256 value;
uint256 balance;
uint256 fee;
address tokenAddress;
bool isSwapped;
bool isExecuted;
}
文件 4 的 16:DealPointDataInternal.sol
pragma solidity ^0.8.17;
struct DealPointDataInternal {
uint256 dealId;
uint256 value;
address from;
address to;
}
文件 5 的 16:DealPointRef.sol
pragma solidity ^0.8.17;
struct DealPointRef {
address controller;
uint256 id;
}
文件 6 的 16:DealPointsController.sol
pragma solidity ^0.8.17;
import './IDealPointsController.sol';
import './IDealsController.sol';
import './DealPointDataInternal.sol';
abstract contract DealPointsController is IDealPointsController {
IDealsController immutable _dealsController;
mapping(uint256 => DealPointDataInternal) internal _data;
mapping(uint256 => uint256) internal _balances;
mapping(uint256 => uint256) internal _fee;
mapping(uint256 => bool) internal _isExecuted;
mapping(uint256 => address) internal _tokenAddress;
constructor(address dealsController_) {
_dealsController = IDealsController(dealsController_);
}
receive() external payable {}
modifier onlyDealsController() {
require(
address(_dealsController) == msg.sender,
'only deals controller can call this function'
);
_;
}
modifier onlyFactory() {
require(
_dealsController.isFactory(msg.sender),
'only factory can call this function'
);
_;
}
function isSwapped(uint256 pointId) external view returns (bool) {
return _dealsController.isSwapped(_data[pointId].dealId);
}
function isExecuted(uint256 pointId) external view returns (bool) {
return _isExecuted[pointId];
}
function dealId(uint256 pointId) external view returns (uint256) {
return _data[pointId].dealId;
}
function from(uint256 pointId) external view returns (address) {
return _data[pointId].from;
}
function to(uint256 pointId) external view returns (address) {
return _data[pointId].to;
}
function setTo(uint256 pointId, address account)
external
onlyDealsController
{
require(
_data[pointId].to == address(0),
'to can be setted only once for deal point'
);
_data[pointId].to = account;
}
function tokenAddress(uint256 pointId) external view returns (address) {
return _tokenAddress[pointId];
}
function value(uint256 pointId) external view returns (uint256) {
return _data[pointId].value;
}
function balance(uint256 pointId) external view returns (uint256) {
return _balances[pointId];
}
function fee(uint256 pointId) external view returns (uint256) {
return _fee[pointId];
}
function owner(uint256 pointId) external view returns (address) {
DealPointDataInternal memory point = _data[pointId];
return this.isSwapped(pointId) ? point.to : point.from;
}
function dealsController() external view returns (address) {
return address(_dealsController);
}
function withdraw(uint256 pointId) external payable onlyDealsController {
address ownerAddr = this.owner(pointId);
DealPointDataInternal memory point = _data[pointId];
require(
_balances[pointId] > 0,
'has no balance to withdraw'
);
require(
address(_dealsController) == msg.sender || ownerAddr == msg.sender,
'only owner or deals controller can withdraw'
);
if (ownerAddr == point.from) _isExecuted[pointId] = false;
uint256 withdrawCount = _balances[pointId];
_balances[pointId] = 0;
require(withdrawCount > 0, 'not enough balance');
_withdraw(pointId, ownerAddr, withdrawCount);
}
function execute(uint256 pointId, address addr)
external
payable
onlyDealsController
{
DealPointDataInternal storage point = _data[pointId];
if (_isExecuted[pointId]) return;
if (point.from == address(0)) point.from = addr;
_execute(pointId, addr);
_isExecuted[pointId] = true;
}
function _execute(uint256 pointId, address from) internal virtual;
function _withdraw(
uint256 pointId,
address withdrawAddr,
uint256 withdrawCount
) internal virtual;
}
文件 7 的 16:Erc20DealPointsController.sol
pragma solidity ^0.8.17;
import '../../DealPointsController.sol';
import './IErc20DealPointsController.sol';
import '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';
import '@openzeppelin/contracts/token/ERC20/IERC20.sol';
import '../../DealPointRef.sol';
import './../../DealPointDataInternal.sol';
contract Erc20DealPointsController is
DealPointsController,
IErc20DealPointsController
{
using SafeERC20 for IERC20;
constructor(address dealsController_)
DealPointsController(dealsController_)
{}
function dealPointTypeId() external pure returns (uint256) {
return 2;
}
function createPoint(
uint256 dealId_,
address from_,
address to_,
address token_,
uint256 count_
) external onlyFactory {
uint256 pointId = _dealsController.getTotalDealPointsCount() + 1;
_data[pointId] = DealPointDataInternal(dealId_, count_, from_, to_);
_tokenAddress[pointId] = token_;
_dealsController.addDealPoint(dealId_, address(this), pointId);
}
function _execute(uint256 pointId, address from) internal virtual override {
DealPointDataInternal memory point = _data[pointId];
IERC20 token = IERC20(_tokenAddress[pointId]);
uint256 lastBalance = token.balanceOf(address(this));
token.safeTransferFrom(from, address(this), point.value);
uint256 pointBalance = token.balanceOf(address(this)) - lastBalance;
_balances[pointId] = pointBalance;
_fee[pointId] =
(pointBalance * _dealsController.feePercent()) /
_dealsController.feeDecimals();
}
function _withdraw(
uint256 pointId,
address withdrawAddr,
uint256 withdrawCount
) internal virtual override {
if (!this.isSwapped(pointId)) _fee[pointId] = 0;
uint256 toTransfer = withdrawCount - _fee[pointId];
IERC20 token = IERC20(_tokenAddress[pointId]);
if (_fee[pointId] > 0)
token.safeTransfer(_dealsController.feeAddress(), _fee[pointId]);
token.safeTransfer(withdrawAddr, toTransfer);
}
function feeIsEthOnWithdraw() external pure returns (bool) {
return false;
}
function executeEtherValue(uint256 pointId) external pure returns(uint256){
return 0;
}
}
文件 8 的 16:IDealPointsController.sol
pragma solidity ^0.8.17;
interface IDealPointsController {
receive() external payable;
function dealPointTypeId() external pure returns (uint256);
function dealId(uint256 pointId) external view returns (uint256);
function tokenAddress(uint256 pointId) external view returns (address);
function from(uint256 pointId) external view returns (address);
function to(uint256 pointId) external view returns (address);
function setTo(uint256 pointId, address account) external;
function value(uint256 pointId) external view returns (uint256);
function balance(uint256 pointId) external view returns (uint256);
function fee(uint256 pointId) external view returns (uint256);
function feeIsEthOnWithdraw() external pure returns (bool);
function owner(uint256 pointId) external view returns (address);
function dealsController() external view returns (address);
function isSwapped(uint256 pointId) external view returns (bool);
function isExecuted(uint256 pointId) external view returns (bool);
function execute(uint256 pointId, address addr) external payable;
function executeEtherValue(uint256 pointId) external view returns(uint256);
function withdraw(uint256 pointId) external payable;
}
文件 9 的 16:IDealsController.sol
pragma solidity ^0.8.17;
import '../fee/IFeeSettings.sol';
import '../lib/factories/IHasFactories.sol';
import './Deal.sol';
import './DealPointData.sol';
interface IDealsController is IFeeSettings, IHasFactories {
event NewDeal(uint256 indexed dealId, address indexed creator);
event Swap(uint256 indexed dealId);
event Execute(uint256 indexed dealId, address account, bool executed);
event OnWithdraw(uint256 indexed dealId, address indexed account);
function swap(uint256 dealId) external;
function isSwapped(uint256 dealId) external view returns (bool);
function getTotalDealPointsCount() external view returns (uint256);
function createDeal(address owner1, address owner2)
external
returns (uint256);
function getDeal(uint256 dealId)
external
view
returns (Deal memory, DealPointData[] memory);
function getDealHeader(uint256 dealId) external view returns (Deal memory);
function addDealPoint(
uint256 dealId,
address dealPointsController,
uint256 newPointId
) external;
function getDealPoint(uint256 dealId, uint256 pointIndex)
external
view
returns (DealPointData memory);
function getDealPointsCount(uint256 dealId) external view returns (uint256);
function isExecuted(uint256 dealId) external view returns (bool);
function withdraw(uint256 dealId) external payable;
function stopDealEditing(uint256 dealId) external;
function execute(uint256 dealId) external payable;
function executeEtherValue(uint256 dealId, uint256 ownerNumber) external view returns(uint256);
function feeEthOnWithdraw(uint256 dealId, uint256 ownerNumber)
external
view
returns (uint256);
}
文件 10 的 16: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);
}
文件 11 的 16:IErc20DealPointsController.sol
pragma solidity ^0.8.17;
import '../../IDealPointsController.sol';
interface IErc20DealPointsController is IDealPointsController {
function createPoint(
uint256 dealId_,
address from_,
address to_,
address token_,
uint256 count_
) external;
}
文件 12 的 16:IFeeSettings.sol
pragma solidity ^0.8.17;
interface IFeeSettings {
function feeAddress() external returns (address);
function feePercent() external returns (uint256);
function feeDecimals() external view returns(uint256);
function feeEth() external returns (uint256);
}
文件 13 的 16:IHasFactories.sol
pragma solidity ^0.8.17;
import '../ownable/IOwnable.sol';
interface IHasFactories is IOwnable {
function isFactory(address addr) external view returns (bool);
function addFactory(address factory) external;
function removeFactory(address factory) external;
function setFactories(address[] calldata addresses, bool isFactory_)
external;
}
文件 14 的 16:IOwnable.sol
pragma solidity ^0.8.17;
interface IOwnable {
function owner() external view returns (address);
function transferOwnership(address newOwner) external;
}
文件 15 的 16:SafeERC20.sol
pragma solidity ^0.8.0;
import "../IERC20.sol";
import "../extensions/draft-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 newAllowance = token.allowance(address(this), spender) + value;
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
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");
uint256 newAllowance = oldAllowance - value;
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
}
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");
if (returndata.length > 0) {
require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
}
}
}
文件 16 的 16:draft-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);
}
{
"compilationTarget": {
"contracts/swapper/plugins/erc20/Erc20DealPointsController.sol": "Erc20DealPointsController"
},
"evmVersion": "london",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": []
}
[{"inputs":[{"internalType":"address","name":"dealsController_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"uint256","name":"pointId","type":"uint256"}],"name":"balance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"dealId_","type":"uint256"},{"internalType":"address","name":"from_","type":"address"},{"internalType":"address","name":"to_","type":"address"},{"internalType":"address","name":"token_","type":"address"},{"internalType":"uint256","name":"count_","type":"uint256"}],"name":"createPoint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"pointId","type":"uint256"}],"name":"dealId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"dealPointTypeId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"dealsController","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"pointId","type":"uint256"},{"internalType":"address","name":"addr","type":"address"}],"name":"execute","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"pointId","type":"uint256"}],"name":"executeEtherValue","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"pointId","type":"uint256"}],"name":"fee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"feeIsEthOnWithdraw","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"pointId","type":"uint256"}],"name":"from","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"pointId","type":"uint256"}],"name":"isExecuted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"pointId","type":"uint256"}],"name":"isSwapped","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"pointId","type":"uint256"}],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"pointId","type":"uint256"},{"internalType":"address","name":"account","type":"address"}],"name":"setTo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"pointId","type":"uint256"}],"name":"to","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"pointId","type":"uint256"}],"name":"tokenAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"pointId","type":"uint256"}],"name":"value","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"pointId","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"payable","type":"function"},{"stateMutability":"payable","type":"receive"}]