文件 1 的 20:Address.sol
pragma solidity >=0.6.2 <0.8.0;
library Address {
function isContract(address account) internal view returns (bool) {
uint256 size;
assembly { size := extcodesize(account) }
return size > 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 _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private 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 的 20:Context.sol
pragma solidity >=0.6.0 <0.8.0;
abstract contract Context {
function _msgSender() internal view virtual returns (address payable) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes memory) {
this;
return msg.data;
}
}
文件 3 的 20:DelegateCall.sol
pragma solidity ^0.7.6;
pragma experimental "ABIEncoderV2";
library DelegateCall {
function isContract(address account) internal view returns (bool) {
uint256 size;
assembly {
size := extcodesize(account)
}
return size > 0;
}
function functionDelegateCall(address target, bytes memory data) 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, "Address: low-level delegate call failed");
}
function _verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) private 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);
}
}
}
}
文件 4 的 20:DomaniDex.sol
pragma solidity ^0.7.6;
pragma experimental "ABIEncoderV2";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {IDomaniDex} from "./interfaces/IDomaniDex.sol";
import {IController} from "../interfaces/IController.sol";
import {IDomani} from "../interfaces/IDomani.sol";
import {IBasicIssuanceModule} from "../interfaces/IBasicIssuanceModule.sol";
import {IWNative} from "./interfaces/IWNative.sol";
import {SafeMath} from "@openzeppelin/contracts/math/SafeMath.sol";
import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/SafeERC20.sol";
import {SafeCast} from "@openzeppelin/contracts/utils/SafeCast.sol";
import {PreciseUnitMath} from "../lib/PreciseUnitMath.sol";
import {ExplicitERC20} from "../lib/ExplicitERC20.sol";
import {Address} from "@openzeppelin/contracts/utils/Address.sol";
import {DelegateCall} from "./lib/DelegateCall.sol";
import {DomaniDexConstants} from "./lib/DomaniDexConstants.sol";
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
import {ReentrancyGuard} from "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
contract DomaniDex is IDomaniDex, Ownable, ReentrancyGuard {
using SafeMath for uint256;
using SafeERC20 for IERC20;
using SafeERC20 for IDomani;
using PreciseUnitMath for uint256;
using SafeCast for int256;
using Address for address payable;
using DelegateCall for address;
string private constant EXACT_INPUT_SIG =
"swapExactInput(bytes,(uint256,uint256,bytes,bool,uint256,address))";
string private constant EXACT_OUTPUT_SIG =
"swapExactOutput(bytes,(uint256,uint256,bytes,bool,uint256,address))";
IController public immutable override controller;
IWNative public immutable override wNative;
IBasicIssuanceModule public override basicIssuanceModule;
mapping(bytes32 => Implementation) private idToImplementation;
modifier onlyValidFund(IDomani _fund) {
require(controller.isSet(address(_fund)), "Must be a valid Domani fund");
_;
}
constructor(
IController _controller,
IBasicIssuanceModule _basicIssuanceModule,
IWNative _wNative,
address _owner
) {
controller = _controller;
_setBasicIssuanceModule(_basicIssuanceModule, _controller);
wNative = _wNative;
transferOwnership(_owner);
}
receive() external payable {}
function setBasicIssuanceModule(IBasicIssuanceModule _basicIssuanceModule) external onlyOwner {
_setBasicIssuanceModule(_basicIssuanceModule, controller);
}
function registerImplementation(
string calldata _identifier,
address _dexAddr,
bytes calldata _dexInfo
) external onlyOwner() {
require(_dexAddr != address(0), "Implementation address can not be the 0x00");
Implementation storage implementation = idToImplementation[keccak256(abi.encode(_identifier))];
implementation.dexAddr = _dexAddr;
implementation.dexInfo = _dexInfo;
emit ImplementationRegistered(_identifier, _dexAddr, _dexInfo);
}
function removeImplementation(string calldata _identifier) external onlyOwner() {
bytes32 identifierHash = keccak256(abi.encode(_identifier));
require(
idToImplementation[identifierHash].dexAddr != address(0),
"Implementation with this id is not registered"
);
delete idToImplementation[identifierHash];
emit ImplementationRemoved(_identifier);
}
function buyDomaniFund(InputDexParams calldata _inputDexParams)
external
payable
override
nonReentrant
onlyValidFund(_inputDexParams.fund)
returns (uint256 inputAmountUsed)
{
require(block.timestamp <= _inputDexParams.expiration, "Transaction expired");
bool isNativeInput = address(_inputDexParams.swapToken) == DomaniDexConstants.NATIVE_ADDR;
if (!isNativeInput) {
require(msg.value == 0, "ETH not required for an ERC20 transfer");
ExplicitERC20.transferFrom(
_inputDexParams.swapToken,
msg.sender,
address(this),
_inputDexParams.maxOrMinSwapTokenAmount
);
}
uint256 startingAmount = isNativeInput ? msg.value : _inputDexParams.maxOrMinSwapTokenAmount;
uint256 remainingInputAmount = startingAmount;
(address[] memory components, uint256[] memory notionalUnits) = getRequiredComponents(
_inputDexParams.fund,
_inputDexParams.fundQuantity,
true
);
uint256 componentsNumber = components.length;
require(componentsNumber == _inputDexParams.swaps.length, "Wrong number of input swaps");
for (uint256 i = 0; i < componentsNumber; i++) {
if (address(_inputDexParams.swapToken) == components[i]) {
remainingInputAmount = remainingInputAmount.sub(notionalUnits[i]);
} else if (isNativeInput && components[i] == address(wNative)) {
wNative.deposit{value: notionalUnits[i]}();
remainingInputAmount = remainingInputAmount.sub(notionalUnits[i]);
} else {
Swap memory swap = _inputDexParams.swaps[i];
Implementation storage implementation = idToImplementation[
keccak256(abi.encode(swap.identifier))
];
address dexAddress = implementation.dexAddr;
require(dexAddress != address(0), "Implementation not supported");
SwapParams memory swapParams = SwapParams(
notionalUnits[i],
remainingInputAmount,
swap.swapData,
isNativeInput,
_inputDexParams.expiration,
address(this)
);
bytes memory result = dexAddress.functionDelegateCall(
abi.encodeWithSignature(EXACT_OUTPUT_SIG, implementation.dexInfo, swapParams)
);
ReturnValues memory returnValues = abi.decode(result, (ReturnValues));
require(
returnValues.inputToken == address(_inputDexParams.swapToken) &&
returnValues.outputToken == components[i],
"Wrong input or output token in the swap"
);
remainingInputAmount = remainingInputAmount.sub(returnValues.inputAmount);
}
IERC20(components[i]).safeApprove(address(basicIssuanceModule), notionalUnits[i]);
}
if (remainingInputAmount > 0) {
if (isNativeInput) {
msg.sender.sendValue(remainingInputAmount);
} else {
_inputDexParams.swapToken.safeTransfer(msg.sender, remainingInputAmount);
}
}
basicIssuanceModule.issue(
_inputDexParams.fund,
_inputDexParams.fundQuantity,
_inputDexParams.recipient
);
inputAmountUsed = startingAmount.sub(remainingInputAmount);
emit DomaniSwap(
msg.sender,
address(_inputDexParams.swapToken),
inputAmountUsed,
_inputDexParams.recipient,
address(_inputDexParams.fund),
_inputDexParams.fundQuantity
);
}
function sellDomaniFund(InputDexParams calldata _inputDexParams)
external
override
nonReentrant
onlyValidFund(_inputDexParams.fund)
returns (uint256 outputAmountReceived)
{
require(block.timestamp <= _inputDexParams.expiration, "Transaction expired");
ExplicitERC20.transferFrom(
_inputDexParams.fund,
msg.sender,
address(this),
_inputDexParams.fundQuantity
);
(address[] memory components, uint256[] memory notionalUnits) = getRequiredComponents(
_inputDexParams.fund,
_inputDexParams.fundQuantity,
false
);
uint256 componentsNumber = components.length;
require(componentsNumber == _inputDexParams.swaps.length, "Wrong number of input swaps");
basicIssuanceModule.redeem(_inputDexParams.fund, _inputDexParams.fundQuantity, address(this));
bool isNativeOutput = address(_inputDexParams.swapToken) == DomaniDexConstants.NATIVE_ADDR;
address dexAddress;
bytes memory result;
for (uint256 i = 0; i < componentsNumber; i++) {
if (address(_inputDexParams.swapToken) == components[i]) {
outputAmountReceived = outputAmountReceived.add(notionalUnits[i]);
_inputDexParams.swapToken.safeTransfer(_inputDexParams.recipient, notionalUnits[i]);
} else if (isNativeOutput && components[i] == address(wNative)) {
wNative.withdraw(notionalUnits[i]);
outputAmountReceived = outputAmountReceived.add(notionalUnits[i]);
payable(_inputDexParams.recipient).sendValue(notionalUnits[i]);
} else {
Swap memory swap = _inputDexParams.swaps[i];
Implementation storage implementation = idToImplementation[
keccak256(abi.encode(swap.identifier))
];
dexAddress = implementation.dexAddr;
require(dexAddress != address(0), "Implementation not supported");
SwapParams memory swapParams = SwapParams(
notionalUnits[i],
0,
swap.swapData,
isNativeOutput,
_inputDexParams.expiration,
_inputDexParams.recipient
);
result = dexAddress.functionDelegateCall(
abi.encodeWithSignature(EXACT_INPUT_SIG, implementation.dexInfo, swapParams)
);
ReturnValues memory returnValues = abi.decode(result, (ReturnValues));
require(
returnValues.inputToken == components[i] &&
returnValues.outputToken == address(_inputDexParams.swapToken),
"Wrong input or output token in the swap"
);
outputAmountReceived = outputAmountReceived.add(returnValues.outputAmount);
}
}
require(
outputAmountReceived >= _inputDexParams.maxOrMinSwapTokenAmount,
"Amount received less than minimum"
);
emit DomaniSwap(
msg.sender,
address(_inputDexParams.fund),
_inputDexParams.fundQuantity,
_inputDexParams.recipient,
address(_inputDexParams.swapToken),
outputAmountReceived
);
}
function sweepToken(IERC20 _token, address payable _recipient)
external
override
nonReentrant
returns (uint256)
{
bool isETH = address(_token) == DomaniDexConstants.NATIVE_ADDR;
uint256 balance = isETH ? address(this).balance : _token.balanceOf(address(this));
if (balance > 0) {
if (isETH) {
_recipient.sendValue(balance);
} else {
_token.safeTransfer(_recipient, balance);
}
}
return balance;
}
function getImplementation(string calldata _identifier)
external
view
override
returns (Implementation memory)
{
return idToImplementation[keccak256(abi.encode(_identifier))];
}
function nativeTokenAddress() external pure override returns (address) {
return DomaniDexConstants.NATIVE_ADDR;
}
function getRequiredComponents(
IDomani _fund,
uint256 _quantity,
bool _isIssue
) public view override onlyValidFund(_fund) returns (address[] memory, uint256[] memory) {
address[] memory components = _fund.getComponents();
uint256[] memory notionalUnits = new uint256[](components.length);
uint256 singleUnit;
for (uint256 i = 0; i < components.length; i++) {
singleUnit = _fund.getDefaultPositionRealUnit(components[i]).toUint256();
notionalUnits[i] = _isIssue
? singleUnit.preciseMulCeil(_quantity)
: singleUnit.preciseMul(_quantity);
}
return (components, notionalUnits);
}
function _setBasicIssuanceModule(
IBasicIssuanceModule _basicIssuanceModule,
IController _controller
) internal {
require(_controller.isModule(address(_basicIssuanceModule)), "Module not valid");
basicIssuanceModule = _basicIssuanceModule;
}
}
文件 5 的 20:DomaniDexConstants.sol
pragma solidity ^0.7.6;
library DomaniDexConstants {
address public constant NATIVE_ADDR = 0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF;
}
文件 6 的 20:ExplicitERC20.sol
pragma solidity 0.7.6;
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/SafeERC20.sol";
import {SafeMath} from "@openzeppelin/contracts/math/SafeMath.sol";
library ExplicitERC20 {
using SafeMath for uint256;
function transferFrom(
IERC20 _token,
address _from,
address _to,
uint256 _quantity
) internal {
if (_quantity > 0) {
uint256 existingBalance = _token.balanceOf(_to);
SafeERC20.safeTransferFrom(_token, _from, _to, _quantity);
uint256 newBalance = _token.balanceOf(_to);
require(newBalance == existingBalance.add(_quantity), "Invalid post transfer balance");
}
}
}
文件 7 的 20:IBasicIssuanceModule.sol
pragma solidity 0.7.6;
import {IDomani} from "./IDomani.sol";
interface IBasicIssuanceModule {
function getRequiredComponentUnitsForIssue(IDomani _setToken, uint256 _quantity)
external
returns (address[] memory, uint256[] memory);
function issue(
IDomani _setToken,
uint256 _quantity,
address _to
) external;
function redeem(
IDomani _setToken,
uint256 _quantity,
address _to
) external;
}
文件 8 的 20:IController.sol
pragma solidity 0.7.6;
interface IController {
function addSet(address _setToken) external;
function feeRecipient() external view returns (address);
function getModuleFee(address _module, uint256 _feeType) external view returns (uint256);
function isModule(address _module) external view returns (bool);
function isSet(address _setToken) external view returns (bool);
function isSystemContract(address _contractAddress) external view returns (bool);
function resourceId(uint256 _id) external view returns (address);
}
文件 9 的 20:IDomani.sol
pragma solidity 0.7.6;
pragma experimental "ABIEncoderV2";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
interface IDomani is IERC20 {
enum ModuleState {
NONE,
PENDING,
INITIALIZED
}
struct Position {
address component;
address module;
int256 unit;
uint8 positionState;
bytes data;
}
struct ComponentPosition {
int256 virtualUnit;
address[] externalPositionModules;
mapping(address => ExternalPosition) externalPositions;
}
struct ExternalPosition {
int256 virtualUnit;
bytes data;
}
function addComponent(address _component) external;
function removeComponent(address _component) external;
function editDefaultPositionUnit(address _component, int256 _realUnit) external;
function addExternalPositionModule(address _component, address _positionModule) external;
function removeExternalPositionModule(address _component, address _positionModule) external;
function editExternalPositionUnit(
address _component,
address _positionModule,
int256 _realUnit
) external;
function editExternalPositionData(
address _component,
address _positionModule,
bytes calldata _data
) external;
function invoke(
address _target,
uint256 _value,
bytes calldata _data
) external returns (bytes memory);
function editPositionMultiplier(int256 _newMultiplier) external;
function mint(address _account, uint256 _quantity) external;
function burn(address _account, uint256 _quantity) external;
function lock() external;
function unlock() external;
function addModule(address _module) external;
function removeModule(address _module) external;
function initializeModule() external;
function setManager(address _manager) external;
function manager() external view returns (address);
function moduleStates(address _module) external view returns (ModuleState);
function getModules() external view returns (address[] memory);
function getDefaultPositionRealUnit(address _component) external view returns (int256);
function getExternalPositionRealUnit(address _component, address _positionModule)
external
view
returns (int256);
function getComponents() external view returns (address[] memory);
function getExternalPositionModules(address _component) external view returns (address[] memory);
function getExternalPositionData(address _component, address _positionModule)
external
view
returns (bytes memory);
function isExternalPositionModule(address _component, address _module)
external
view
returns (bool);
function isComponent(address _component) external view returns (bool);
function positionMultiplier() external view returns (int256);
function getPositions() external view returns (Position[] memory);
function getTotalComponentRealUnits(address _component) external view returns (int256);
function isInitializedModule(address _module) external view returns (bool);
function isPendingModule(address _module) external view returns (bool);
function isLocked() external view returns (bool);
}
文件 10 的 20:IDomaniDex.sol
pragma solidity >=0.7.6;
pragma experimental "ABIEncoderV2";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {IDomani} from "../../interfaces/IDomani.sol";
import {IController} from "../../interfaces/IController.sol";
import {IBasicIssuanceModule} from "../../interfaces/IBasicIssuanceModule.sol";
import {IWNative} from "../interfaces/IWNative.sol";
import {IDomaniDexGeneral} from "./IDomaniDexGeneral.sol";
interface IDomaniDex is IDomaniDexGeneral {
struct Swap {
string identifier;
bytes swapData;
}
struct InputDexParams {
IDomani fund;
uint256 fundQuantity;
IERC20 swapToken;
uint256 maxOrMinSwapTokenAmount;
Swap[] swaps;
uint256 expiration;
address recipient;
}
event DomaniSwap(
address indexed sender,
address inputToken,
uint256 inputAmount,
address indexed recipient,
address outputToken,
uint256 outputAmount
);
function buyDomaniFund(InputDexParams calldata _inputDexParams)
external
payable
returns (uint256 inputAmountUsed);
function sellDomaniFund(InputDexParams calldata _inputDexParams)
external
returns (uint256 outputAmountReceived);
function sweepToken(IERC20 token, address payable recipient) external returns (uint256);
function controller() external view returns (IController);
function wNative() external view returns (IWNative);
function basicIssuanceModule() external view returns (IBasicIssuanceModule);
function getRequiredComponents(
IDomani _fund,
uint256 _quantity,
bool _isIssue
) external view returns (address[] memory, uint256[] memory);
function nativeTokenAddress() external pure returns (address);
}
文件 11 的 20:IDomaniDexGeneral.sol
pragma solidity >=0.7.6;
pragma experimental "ABIEncoderV2";
interface IDomaniDexGeneral {
struct ReturnValues {
address inputToken;
address outputToken;
uint256 inputAmount;
uint256 outputAmount;
}
struct SwapParams {
uint256 exactAmount;
uint256 minOutOrMaxIn;
bytes extraData;
bool isNative;
uint256 expiration;
address recipient;
}
struct Implementation {
address dexAddr;
bytes dexInfo;
}
event ImplementationRegistered(
string indexed id,
address implementationAddr,
bytes implementationInfo
);
event ImplementationRemoved(string indexed id);
function getImplementation(string calldata identifier)
external
view
returns (Implementation memory);
}
文件 12 的 20:IERC20.sol
pragma solidity >=0.6.0 <0.8.0;
interface IERC20 {
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(address recipient, 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 sender, address recipient, uint256 amount) external returns (bool);
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
}
文件 13 的 20:IWNative.sol
pragma solidity >=0.7.6;
interface IWNative {
function deposit() external payable;
function withdraw(uint256 _amount) external;
}
文件 14 的 20:Ownable.sol
pragma solidity >=0.6.0 <0.8.0;
import "../GSN/Context.sol";
abstract contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
constructor () internal {
address msgSender = _msgSender();
_owner = msgSender;
emit OwnershipTransferred(address(0), msgSender);
}
function owner() public view returns (address) {
return _owner;
}
modifier onlyOwner() {
require(_owner == _msgSender(), "Ownable: caller is not the owner");
_;
}
function renounceOwnership() public virtual onlyOwner {
emit OwnershipTransferred(_owner, address(0));
_owner = address(0);
}
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
emit OwnershipTransferred(_owner, newOwner);
_owner = newOwner;
}
}
文件 15 的 20:PreciseUnitMath.sol
pragma solidity 0.7.6;
pragma experimental ABIEncoderV2;
import {SafeMath} from "@openzeppelin/contracts/math/SafeMath.sol";
import {SignedSafeMath} from "@openzeppelin/contracts/math/SignedSafeMath.sol";
library PreciseUnitMath {
using SafeMath for uint256;
using SignedSafeMath for int256;
uint256 internal constant PRECISE_UNIT = 10**18;
int256 internal constant PRECISE_UNIT_INT = 10**18;
uint256 internal constant MAX_UINT_256 = type(uint256).max;
int256 internal constant MAX_INT_256 = type(int256).max;
int256 internal constant MIN_INT_256 = type(int256).min;
function preciseUnit() internal pure returns (uint256) {
return PRECISE_UNIT;
}
function preciseUnitInt() internal pure returns (int256) {
return PRECISE_UNIT_INT;
}
function maxUint256() internal pure returns (uint256) {
return MAX_UINT_256;
}
function maxInt256() internal pure returns (int256) {
return MAX_INT_256;
}
function minInt256() internal pure returns (int256) {
return MIN_INT_256;
}
function preciseMul(uint256 a, uint256 b) internal pure returns (uint256) {
return a.mul(b).div(PRECISE_UNIT);
}
function preciseMul(int256 a, int256 b) internal pure returns (int256) {
return a.mul(b).div(PRECISE_UNIT_INT);
}
function preciseMulCeil(uint256 a, uint256 b) internal pure returns (uint256) {
if (a == 0 || b == 0) {
return 0;
}
return a.mul(b).sub(1).div(PRECISE_UNIT).add(1);
}
function preciseDiv(uint256 a, uint256 b) internal pure returns (uint256) {
return a.mul(PRECISE_UNIT).div(b);
}
function preciseDiv(int256 a, int256 b) internal pure returns (int256) {
return a.mul(PRECISE_UNIT_INT).div(b);
}
function preciseDivCeil(uint256 a, uint256 b) internal pure returns (uint256) {
require(b != 0, "Cant divide by 0");
return a > 0 ? a.mul(PRECISE_UNIT).sub(1).div(b).add(1) : 0;
}
function divDown(int256 a, int256 b) internal pure returns (int256) {
require(b != 0, "Cant divide by 0");
require(a != MIN_INT_256 || b != -1, "Invalid input");
int256 result = a.div(b);
if (a ^ b < 0 && a % b != 0) {
result -= 1;
}
return result;
}
function conservativePreciseMul(int256 a, int256 b) internal pure returns (int256) {
return divDown(a.mul(b), PRECISE_UNIT_INT);
}
function conservativePreciseDiv(int256 a, int256 b) internal pure returns (int256) {
return divDown(a.mul(PRECISE_UNIT_INT), b);
}
function safePower(uint256 a, uint256 pow) internal pure returns (uint256) {
require(a > 0, "Value must be positive");
uint256 result = 1;
for (uint256 i = 0; i < pow; i++) {
uint256 previousResult = result;
result = previousResult.mul(a);
}
return result;
}
function approximatelyEquals(
uint256 a,
uint256 b,
uint256 range
) internal pure returns (bool) {
return a <= b.add(range) && a >= b.sub(range);
}
}
文件 16 的 20:ReentrancyGuard.sol
pragma solidity >=0.6.0 <0.8.0;
abstract contract ReentrancyGuard {
uint256 private constant _NOT_ENTERED = 1;
uint256 private constant _ENTERED = 2;
uint256 private _status;
constructor () internal {
_status = _NOT_ENTERED;
}
modifier nonReentrant() {
require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
_status = _ENTERED;
_;
_status = _NOT_ENTERED;
}
}
文件 17 的 20:SafeCast.sol
pragma solidity >=0.6.0 <0.8.0;
library SafeCast {
function toUint128(uint256 value) internal pure returns (uint128) {
require(value < 2**128, "SafeCast: value doesn\'t fit in 128 bits");
return uint128(value);
}
function toUint64(uint256 value) internal pure returns (uint64) {
require(value < 2**64, "SafeCast: value doesn\'t fit in 64 bits");
return uint64(value);
}
function toUint32(uint256 value) internal pure returns (uint32) {
require(value < 2**32, "SafeCast: value doesn\'t fit in 32 bits");
return uint32(value);
}
function toUint16(uint256 value) internal pure returns (uint16) {
require(value < 2**16, "SafeCast: value doesn\'t fit in 16 bits");
return uint16(value);
}
function toUint8(uint256 value) internal pure returns (uint8) {
require(value < 2**8, "SafeCast: value doesn\'t fit in 8 bits");
return uint8(value);
}
function toUint256(int256 value) internal pure returns (uint256) {
require(value >= 0, "SafeCast: value must be positive");
return uint256(value);
}
function toInt128(int256 value) internal pure returns (int128) {
require(value >= -2**127 && value < 2**127, "SafeCast: value doesn\'t fit in 128 bits");
return int128(value);
}
function toInt64(int256 value) internal pure returns (int64) {
require(value >= -2**63 && value < 2**63, "SafeCast: value doesn\'t fit in 64 bits");
return int64(value);
}
function toInt32(int256 value) internal pure returns (int32) {
require(value >= -2**31 && value < 2**31, "SafeCast: value doesn\'t fit in 32 bits");
return int32(value);
}
function toInt16(int256 value) internal pure returns (int16) {
require(value >= -2**15 && value < 2**15, "SafeCast: value doesn\'t fit in 16 bits");
return int16(value);
}
function toInt8(int256 value) internal pure returns (int8) {
require(value >= -2**7 && value < 2**7, "SafeCast: value doesn\'t fit in 8 bits");
return int8(value);
}
function toInt256(uint256 value) internal pure returns (int256) {
require(value < 2**255, "SafeCast: value doesn't fit in an int256");
return int256(value);
}
}
文件 18 的 20:SafeERC20.sol
pragma solidity >=0.6.0 <0.8.0;
import "./IERC20.sol";
import "../../math/SafeMath.sol";
import "../../utils/Address.sol";
library SafeERC20 {
using SafeMath for uint256;
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).add(value);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 newAllowance = token.allowance(address(this), spender).sub(value, "SafeERC20: decreased allowance below zero");
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
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");
}
}
}
文件 19 的 20:SafeMath.sol
pragma solidity >=0.6.0 <0.8.0;
library SafeMath {
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
require(c >= a, "SafeMath: addition overflow");
return c;
}
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
return sub(a, b, "SafeMath: subtraction overflow");
}
function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b <= a, errorMessage);
uint256 c = a - b;
return c;
}
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
if (a == 0) {
return 0;
}
uint256 c = a * b;
require(c / a == b, "SafeMath: multiplication overflow");
return c;
}
function div(uint256 a, uint256 b) internal pure returns (uint256) {
return div(a, b, "SafeMath: division by zero");
}
function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b > 0, errorMessage);
uint256 c = a / b;
return c;
}
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
return mod(a, b, "SafeMath: modulo by zero");
}
function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b != 0, errorMessage);
return a % b;
}
}
文件 20 的 20:SignedSafeMath.sol
pragma solidity >=0.6.0 <0.8.0;
library SignedSafeMath {
int256 constant private _INT256_MIN = -2**255;
function mul(int256 a, int256 b) internal pure returns (int256) {
if (a == 0) {
return 0;
}
require(!(a == -1 && b == _INT256_MIN), "SignedSafeMath: multiplication overflow");
int256 c = a * b;
require(c / a == b, "SignedSafeMath: multiplication overflow");
return c;
}
function div(int256 a, int256 b) internal pure returns (int256) {
require(b != 0, "SignedSafeMath: division by zero");
require(!(b == -1 && a == _INT256_MIN), "SignedSafeMath: division overflow");
int256 c = a / b;
return c;
}
function sub(int256 a, int256 b) internal pure returns (int256) {
int256 c = a - b;
require((b >= 0 && c <= a) || (b < 0 && c > a), "SignedSafeMath: subtraction overflow");
return c;
}
function add(int256 a, int256 b) internal pure returns (int256) {
int256 c = a + b;
require((b >= 0 && c >= a) || (b < 0 && c < a), "SignedSafeMath: addition overflow");
return c;
}
}
{
"compilationTarget": {
"contracts/dex/DomaniDex.sol": "DomaniDex"
},
"evmVersion": "istanbul",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs",
"useLiteralContent": true
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": []
}
[{"inputs":[{"internalType":"contract IController","name":"_controller","type":"address"},{"internalType":"contract IBasicIssuanceModule","name":"_basicIssuanceModule","type":"address"},{"internalType":"contract IWNative","name":"_wNative","type":"address"},{"internalType":"address","name":"_owner","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"address","name":"inputToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"inputAmount","type":"uint256"},{"indexed":true,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"address","name":"outputToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"outputAmount","type":"uint256"}],"name":"DomaniSwap","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"string","name":"id","type":"string"},{"indexed":false,"internalType":"address","name":"implementationAddr","type":"address"},{"indexed":false,"internalType":"bytes","name":"implementationInfo","type":"bytes"}],"name":"ImplementationRegistered","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"string","name":"id","type":"string"}],"name":"ImplementationRemoved","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"},{"inputs":[],"name":"basicIssuanceModule","outputs":[{"internalType":"contract IBasicIssuanceModule","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"contract IDomani","name":"fund","type":"address"},{"internalType":"uint256","name":"fundQuantity","type":"uint256"},{"internalType":"contract IERC20","name":"swapToken","type":"address"},{"internalType":"uint256","name":"maxOrMinSwapTokenAmount","type":"uint256"},{"components":[{"internalType":"string","name":"identifier","type":"string"},{"internalType":"bytes","name":"swapData","type":"bytes"}],"internalType":"struct IDomaniDex.Swap[]","name":"swaps","type":"tuple[]"},{"internalType":"uint256","name":"expiration","type":"uint256"},{"internalType":"address","name":"recipient","type":"address"}],"internalType":"struct IDomaniDex.InputDexParams","name":"_inputDexParams","type":"tuple"}],"name":"buyDomaniFund","outputs":[{"internalType":"uint256","name":"inputAmountUsed","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"controller","outputs":[{"internalType":"contract IController","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"_identifier","type":"string"}],"name":"getImplementation","outputs":[{"components":[{"internalType":"address","name":"dexAddr","type":"address"},{"internalType":"bytes","name":"dexInfo","type":"bytes"}],"internalType":"struct IDomaniDexGeneral.Implementation","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IDomani","name":"_fund","type":"address"},{"internalType":"uint256","name":"_quantity","type":"uint256"},{"internalType":"bool","name":"_isIssue","type":"bool"}],"name":"getRequiredComponents","outputs":[{"internalType":"address[]","name":"","type":"address[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nativeTokenAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"_identifier","type":"string"},{"internalType":"address","name":"_dexAddr","type":"address"},{"internalType":"bytes","name":"_dexInfo","type":"bytes"}],"name":"registerImplementation","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_identifier","type":"string"}],"name":"removeImplementation","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"contract IDomani","name":"fund","type":"address"},{"internalType":"uint256","name":"fundQuantity","type":"uint256"},{"internalType":"contract IERC20","name":"swapToken","type":"address"},{"internalType":"uint256","name":"maxOrMinSwapTokenAmount","type":"uint256"},{"components":[{"internalType":"string","name":"identifier","type":"string"},{"internalType":"bytes","name":"swapData","type":"bytes"}],"internalType":"struct IDomaniDex.Swap[]","name":"swaps","type":"tuple[]"},{"internalType":"uint256","name":"expiration","type":"uint256"},{"internalType":"address","name":"recipient","type":"address"}],"internalType":"struct IDomaniDex.InputDexParams","name":"_inputDexParams","type":"tuple"}],"name":"sellDomaniFund","outputs":[{"internalType":"uint256","name":"outputAmountReceived","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IBasicIssuanceModule","name":"_basicIssuanceModule","type":"address"}],"name":"setBasicIssuanceModule","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"_token","type":"address"},{"internalType":"address payable","name":"_recipient","type":"address"}],"name":"sweepToken","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"wNative","outputs":[{"internalType":"contract IWNative","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]