add initializableERC721
This commit is contained in:
@@ -49,6 +49,7 @@ module.exports = {
|
|||||||
DSPProxy: "0xC5fF477667E29df8887D258CaE593e04A1961A69",
|
DSPProxy: "0xC5fF477667E29df8887D258CaE593e04A1961A69",
|
||||||
CpProxy: "0x0e3DAAa1eCfBF2fA4cb990dC34D760c38279C5a8",
|
CpProxy: "0x0e3DAAa1eCfBF2fA4cb990dC34D760c38279C5a8",
|
||||||
|
|
||||||
|
|
||||||
//vDODO
|
//vDODO
|
||||||
DODOCirculationHelper: "",
|
DODOCirculationHelper: "",
|
||||||
Governance: "",
|
Governance: "",
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ contract ERC721Facotry {
|
|||||||
string memory baseUrl
|
string memory baseUrl
|
||||||
) external returns (address newERC721) {
|
) external returns (address newERC721) {
|
||||||
newERC721 = ICloneFactory(_CLONE_FACTORY_).clone(_ERC721_TEMPLATE_);
|
newERC721 = ICloneFactory(_CLONE_FACTORY_).clone(_ERC721_TEMPLATE_);
|
||||||
InitializableERC721(newERC721).init(msg.sender, name, symbol, baseUrl);
|
InitializableERC721(newERC721).init(name, symbol, baseUrl);
|
||||||
_USER_REGISTRY_[msg.sender].push(newERC721);
|
_USER_REGISTRY_[msg.sender].push(newERC721);
|
||||||
emit NewERC721(newERC721, msg.sender);
|
emit NewERC721(newERC721, msg.sender);
|
||||||
}
|
}
|
||||||
|
|||||||
77
contracts/SmartRoute/proxies/DODOUpCpProxy.sol
Normal file
77
contracts/SmartRoute/proxies/DODOUpCpProxy.sol
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Copyright 2020 DODO ZOO.
|
||||||
|
SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
pragma solidity 0.6.9;
|
||||||
|
|
||||||
|
import {IDODOApproveProxy} from "../DODOApproveProxy.sol";
|
||||||
|
import {IDODOV2} from "./../intf/IDODOV2.sol";
|
||||||
|
import {IERC20} from "../../intf/IERC20.sol";
|
||||||
|
import {SafeERC20} from "../../lib/SafeERC20.sol";
|
||||||
|
import {IWETH} from "../../intf/IWETH.sol";
|
||||||
|
import {SafeMath} from "../../lib/SafeMath.sol";
|
||||||
|
import {SafeERC20} from "../../lib/SafeERC20.sol";
|
||||||
|
import {ReentrancyGuard} from "../../lib/ReentrancyGuard.sol";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @title DODOUpCpProxy
|
||||||
|
* @author DODO Breeder
|
||||||
|
*
|
||||||
|
* @notice UpCrowdPooling Proxy (temporary)
|
||||||
|
*/
|
||||||
|
contract DODOUpCpProxy is ReentrancyGuard {
|
||||||
|
using SafeMath for uint256;
|
||||||
|
using SafeERC20 for IERC20;
|
||||||
|
|
||||||
|
// ============ Storage ============
|
||||||
|
|
||||||
|
address constant _ETH_ADDRESS_ = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;
|
||||||
|
address public immutable _WETH_;
|
||||||
|
address public immutable _UPCP_FACTORY_;
|
||||||
|
|
||||||
|
fallback() external payable {}
|
||||||
|
|
||||||
|
receive() external payable {}
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
address upCpFactory,
|
||||||
|
address payable weth
|
||||||
|
) public {
|
||||||
|
_UPCP_FACTORY_ = upCpFactory;
|
||||||
|
_WETH_ = weth;
|
||||||
|
}
|
||||||
|
|
||||||
|
//============ UpCrowdPooling Functions (create) ============
|
||||||
|
|
||||||
|
function createUpCrowdPooling(
|
||||||
|
address creator,
|
||||||
|
address baseToken,
|
||||||
|
address quoteToken,
|
||||||
|
uint256 baseInAmount,
|
||||||
|
uint256[] memory timeLine,
|
||||||
|
uint256[] memory valueList,
|
||||||
|
bool isOpenTWAP
|
||||||
|
) external payable preventReentrant returns (address payable newUpCrowdPooling) {
|
||||||
|
address _baseToken = baseToken;
|
||||||
|
address _quoteToken = quoteToken == _ETH_ADDRESS_ ? _WETH_ : quoteToken;
|
||||||
|
|
||||||
|
newUpCrowdPooling = IDODOV2(_UPCP_FACTORY_).createCrowdPooling();
|
||||||
|
|
||||||
|
IERC20(_baseToken).safeTransferFrom(msg.sender, newUpCrowdPooling, baseInAmount);
|
||||||
|
|
||||||
|
newUpCrowdPooling.transfer(msg.value);
|
||||||
|
|
||||||
|
IDODOV2(_UPCP_FACTORY_).initCrowdPooling(
|
||||||
|
newUpCrowdPooling,
|
||||||
|
creator,
|
||||||
|
_baseToken,
|
||||||
|
_quoteToken,
|
||||||
|
timeLine,
|
||||||
|
valueList,
|
||||||
|
isOpenTWAP
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
232
contracts/external/ERC721/InitializableERC721.sol
vendored
232
contracts/external/ERC721/InitializableERC721.sol
vendored
@@ -7,29 +7,231 @@
|
|||||||
|
|
||||||
pragma solidity 0.6.9;
|
pragma solidity 0.6.9;
|
||||||
|
|
||||||
// import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
|
import {IERC721} from "../../intf/IERC721.sol";
|
||||||
import {InitializableOwnable} from "../../lib/InitializableOwnable.sol";
|
import {IERC721Receiver} from "../../intf/IERC721Receiver.sol";
|
||||||
|
import {IERC721Metadata} from "../../intf/IERC721Metadata.sol";
|
||||||
|
import {IERC165} from "../../intf/IERC165.sol";
|
||||||
|
import {Strings} from "../../lib/Strings.sol";
|
||||||
|
import {Address} from "../../lib/Address.sol";
|
||||||
|
|
||||||
//TODO:
|
|
||||||
contract InitializableERC721 is InitializableOwnable {
|
contract InitializableERC721 is IERC165, IERC721, IERC721Metadata {
|
||||||
|
|
||||||
|
using Address for address;
|
||||||
|
using Strings for uint256;
|
||||||
|
|
||||||
|
// Token name
|
||||||
|
string private _name;
|
||||||
|
|
||||||
|
// Token symbol
|
||||||
|
string private _symbol;
|
||||||
|
|
||||||
|
// Base URI
|
||||||
|
string private _baseURI;
|
||||||
|
|
||||||
|
// Mapping from token ID to owner address
|
||||||
|
mapping (uint256 => address) private _owners;
|
||||||
|
|
||||||
|
// Mapping owner address to token count
|
||||||
|
mapping (address => uint256) private _balances;
|
||||||
|
|
||||||
|
// Mapping from token ID to approved address
|
||||||
|
mapping (uint256 => address) private _tokenApprovals;
|
||||||
|
|
||||||
|
// Mapping from owner to operator approvals
|
||||||
|
mapping (address => mapping (address => bool)) private _operatorApprovals;
|
||||||
|
|
||||||
|
|
||||||
function init(
|
function init(
|
||||||
address creator,
|
|
||||||
string memory name,
|
string memory name,
|
||||||
string memory symbol,
|
string memory symbol,
|
||||||
string memory baseUrl
|
string memory baseUrI
|
||||||
) public {
|
) public {
|
||||||
initOwner(creator);
|
_name = name;
|
||||||
// super(name,symbol);
|
_symbol = symbol;
|
||||||
|
_baseURI = baseUrI;
|
||||||
|
_safeMint(msg.sender, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// baseUrl overide
|
|
||||||
|
|
||||||
// function mint(string memory _name, address _to) public {
|
function tokenURI(uint256 tokenId) public view override returns (string memory) {
|
||||||
// require(msg.sender == gameOwner, "Only game owner can create new monsters");
|
require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token");
|
||||||
// uint id = monsters.length;
|
|
||||||
// monsters.push(Monster(_name, 1));
|
string memory baseURI = _baseURI;
|
||||||
// _safeMint(_to, id);
|
return bytes(baseURI).length > 0
|
||||||
// }
|
? string(abi.encodePacked(baseURI, tokenId.toString()))
|
||||||
|
: '';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function supportsInterface(bytes4 interfaceId) public view override returns (bool) {
|
||||||
|
return interfaceId == type(IERC721).interfaceId
|
||||||
|
|| interfaceId == type(IERC721Metadata).interfaceId;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function balanceOf(address owner) public view virtual override returns (uint256) {
|
||||||
|
require(owner != address(0), "ERC721: balance query for the zero address");
|
||||||
|
return _balances[owner];
|
||||||
|
}
|
||||||
|
|
||||||
|
function ownerOf(uint256 tokenId) public view virtual override returns (address) {
|
||||||
|
address owner = _owners[tokenId];
|
||||||
|
require(owner != address(0), "ERC721: owner query for nonexistent token");
|
||||||
|
return owner;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function name() public view virtual override returns (string memory) {
|
||||||
|
return _name;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function symbol() public view virtual override returns (string memory) {
|
||||||
|
return _symbol;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function approve(address to, uint256 tokenId) public virtual override {
|
||||||
|
address owner = ownerOf(tokenId);
|
||||||
|
require(to != owner, "ERC721: approval to current owner");
|
||||||
|
|
||||||
|
require(msg.sender == owner || isApprovedForAll(owner, msg.sender),
|
||||||
|
"ERC721: approve caller is not owner nor approved for all"
|
||||||
|
);
|
||||||
|
|
||||||
|
_approve(to, tokenId);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getApproved(uint256 tokenId) public view virtual override returns (address) {
|
||||||
|
require(_exists(tokenId), "ERC721: approved query for nonexistent token");
|
||||||
|
|
||||||
|
return _tokenApprovals[tokenId];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function setApprovalForAll(address operator, bool approved) public virtual override {
|
||||||
|
require(operator != msg.sender, "ERC721: approve to caller");
|
||||||
|
|
||||||
|
_operatorApprovals[msg.sender][operator] = approved;
|
||||||
|
emit ApprovalForAll(msg.sender, operator, approved);
|
||||||
|
}
|
||||||
|
|
||||||
|
function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {
|
||||||
|
return _operatorApprovals[owner][operator];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function transferFrom(address from, address to, uint256 tokenId) public virtual override {
|
||||||
|
//solhint-disable-next-line max-line-length
|
||||||
|
require(_isApprovedOrOwner(msg.sender, tokenId), "ERC721: transfer caller is not owner nor approved");
|
||||||
|
|
||||||
|
_transfer(from, to, tokenId);
|
||||||
|
}
|
||||||
|
|
||||||
|
function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override {
|
||||||
|
safeTransferFrom(from, to, tokenId, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) public virtual override {
|
||||||
|
require(_isApprovedOrOwner(msg.sender, tokenId), "ERC721: transfer caller is not owner nor approved");
|
||||||
|
_safeTransfer(from, to, tokenId, _data);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// =========== internal ==================
|
||||||
|
|
||||||
|
function _safeTransfer(address from, address to, uint256 tokenId, bytes memory _data) internal virtual {
|
||||||
|
_transfer(from, to, tokenId);
|
||||||
|
require(_checkOnERC721Received(from, to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer");
|
||||||
|
}
|
||||||
|
|
||||||
|
function _exists(uint256 tokenId) internal view virtual returns (bool) {
|
||||||
|
return _owners[tokenId] != address(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {
|
||||||
|
require(_exists(tokenId), "ERC721: operator query for nonexistent token");
|
||||||
|
address owner = ownerOf(tokenId);
|
||||||
|
return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, spender));
|
||||||
|
}
|
||||||
|
|
||||||
|
function _safeMint(address to, uint256 tokenId) internal virtual {
|
||||||
|
_safeMint(to, tokenId, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
function _safeMint(address to, uint256 tokenId, bytes memory _data) internal virtual {
|
||||||
|
_mint(to, tokenId);
|
||||||
|
require(_checkOnERC721Received(address(0), to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer");
|
||||||
|
}
|
||||||
|
|
||||||
|
function _mint(address to, uint256 tokenId) internal virtual {
|
||||||
|
require(to != address(0), "ERC721: mint to the zero address");
|
||||||
|
require(!_exists(tokenId), "ERC721: token already minted");
|
||||||
|
|
||||||
|
_beforeTokenTransfer(address(0), to, tokenId);
|
||||||
|
|
||||||
|
_balances[to] += 1;
|
||||||
|
_owners[tokenId] = to;
|
||||||
|
|
||||||
|
emit Transfer(address(0), to, tokenId);
|
||||||
|
}
|
||||||
|
|
||||||
|
function _burn(uint256 tokenId) internal virtual {
|
||||||
|
address owner = ownerOf(tokenId);
|
||||||
|
|
||||||
|
_beforeTokenTransfer(owner, address(0), tokenId);
|
||||||
|
|
||||||
|
// Clear approvals
|
||||||
|
_approve(address(0), tokenId);
|
||||||
|
|
||||||
|
_balances[owner] -= 1;
|
||||||
|
delete _owners[tokenId];
|
||||||
|
|
||||||
|
emit Transfer(owner, address(0), tokenId);
|
||||||
|
}
|
||||||
|
|
||||||
|
function _transfer(address from, address to, uint256 tokenId) internal virtual {
|
||||||
|
require(ownerOf(tokenId) == from, "ERC721: transfer of token that is not own");
|
||||||
|
require(to != address(0), "ERC721: transfer to the zero address");
|
||||||
|
|
||||||
|
_beforeTokenTransfer(from, to, tokenId);
|
||||||
|
|
||||||
|
// Clear approvals from the previous owner
|
||||||
|
_approve(address(0), tokenId);
|
||||||
|
|
||||||
|
_balances[from] -= 1;
|
||||||
|
_balances[to] += 1;
|
||||||
|
_owners[tokenId] = to;
|
||||||
|
|
||||||
|
emit Transfer(from, to, tokenId);
|
||||||
|
}
|
||||||
|
|
||||||
|
function _approve(address to, uint256 tokenId) internal virtual {
|
||||||
|
_tokenApprovals[tokenId] = to;
|
||||||
|
emit Approval(ownerOf(tokenId), to, tokenId);
|
||||||
|
}
|
||||||
|
|
||||||
|
function _checkOnERC721Received(address from, address to, uint256 tokenId, bytes memory _data)
|
||||||
|
private returns (bool)
|
||||||
|
{
|
||||||
|
if (to.isContract()) {
|
||||||
|
try IERC721Receiver(to).onERC721Received(msg.sender, from, tokenId, _data) returns (bytes4 retval) {
|
||||||
|
return retval == IERC721Receiver(to).onERC721Received.selector;
|
||||||
|
} catch (bytes memory reason) {
|
||||||
|
if (reason.length == 0) {
|
||||||
|
revert("ERC721: transfer to non ERC721Receiver implementer");
|
||||||
|
} else {
|
||||||
|
// solhint-disable-next-line no-inline-assembly
|
||||||
|
assembly {
|
||||||
|
revert(add(32, reason), mload(reason))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function _beforeTokenTransfer(address from, address to, uint256 tokenId) internal virtual { }
|
||||||
}
|
}
|
||||||
|
|||||||
28
contracts/intf/IERC721Metadata.sol
Normal file
28
contracts/intf/IERC721Metadata.sol
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
// This is a file copied from https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/extensions/IERC721Metadata.sol
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
pragma solidity 0.6.9;
|
||||||
|
|
||||||
|
import "./IERC721.sol";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @title ERC-721 Non-Fungible Token Standard, optional metadata extension
|
||||||
|
* @dev See https://eips.ethereum.org/EIPS/eip-721
|
||||||
|
*/
|
||||||
|
interface IERC721Metadata is IERC721 {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dev Returns the token collection name.
|
||||||
|
*/
|
||||||
|
function name() external view returns (string memory);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dev Returns the token collection symbol.
|
||||||
|
*/
|
||||||
|
function symbol() external view returns (string memory);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.
|
||||||
|
*/
|
||||||
|
function tokenURI(uint256 tokenId) external view returns (string memory);
|
||||||
|
}
|
||||||
190
contracts/lib/Address.sol
Normal file
190
contracts/lib/Address.sol
Normal file
@@ -0,0 +1,190 @@
|
|||||||
|
// This is a file copied from https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/Address.sol
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
pragma solidity 0.6.9;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dev Collection of functions related to the address type
|
||||||
|
*/
|
||||||
|
library Address {
|
||||||
|
/**
|
||||||
|
* @dev Returns true if `account` is a contract.
|
||||||
|
*
|
||||||
|
* [IMPORTANT]
|
||||||
|
* ====
|
||||||
|
* It is unsafe to assume that an address for which this function returns
|
||||||
|
* false is an externally-owned account (EOA) and not a contract.
|
||||||
|
*
|
||||||
|
* Among others, `isContract` will return false for the following
|
||||||
|
* types of addresses:
|
||||||
|
*
|
||||||
|
* - an externally-owned account
|
||||||
|
* - a contract in construction
|
||||||
|
* - an address where a contract will be created
|
||||||
|
* - an address where a contract lived, but was destroyed
|
||||||
|
* ====
|
||||||
|
*/
|
||||||
|
function isContract(address account) internal view returns (bool) {
|
||||||
|
// This method relies on extcodesize, which returns 0 for contracts in
|
||||||
|
// construction, since the code is only stored at the end of the
|
||||||
|
// constructor execution.
|
||||||
|
|
||||||
|
uint256 size;
|
||||||
|
// solhint-disable-next-line no-inline-assembly
|
||||||
|
assembly { size := extcodesize(account) }
|
||||||
|
return size > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dev Replacement for Solidity's `transfer`: sends `amount` wei to
|
||||||
|
* `recipient`, forwarding all available gas and reverting on errors.
|
||||||
|
*
|
||||||
|
* https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
|
||||||
|
* of certain opcodes, possibly making contracts go over the 2300 gas limit
|
||||||
|
* imposed by `transfer`, making them unable to receive funds via
|
||||||
|
* `transfer`. {sendValue} removes this limitation.
|
||||||
|
*
|
||||||
|
* https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
|
||||||
|
*
|
||||||
|
* IMPORTANT: because control is transferred to `recipient`, care must be
|
||||||
|
* taken to not create reentrancy vulnerabilities. Consider using
|
||||||
|
* {ReentrancyGuard} or the
|
||||||
|
* https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
|
||||||
|
*/
|
||||||
|
function sendValue(address payable recipient, uint256 amount) internal {
|
||||||
|
require(address(this).balance >= amount, "Address: insufficient balance");
|
||||||
|
|
||||||
|
// solhint-disable-next-line avoid-low-level-calls, avoid-call-value
|
||||||
|
(bool success, ) = recipient.call{ value: amount }("");
|
||||||
|
require(success, "Address: unable to send value, recipient may have reverted");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dev Performs a Solidity function call using a low level `call`. A
|
||||||
|
* plain`call` is an unsafe replacement for a function call: use this
|
||||||
|
* function instead.
|
||||||
|
*
|
||||||
|
* If `target` reverts with a revert reason, it is bubbled up by this
|
||||||
|
* function (like regular Solidity function calls).
|
||||||
|
*
|
||||||
|
* Returns the raw returned data. To convert to the expected return value,
|
||||||
|
* use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
|
||||||
|
*
|
||||||
|
* Requirements:
|
||||||
|
*
|
||||||
|
* - `target` must be a contract.
|
||||||
|
* - calling `target` with `data` must not revert.
|
||||||
|
*
|
||||||
|
* _Available since v3.1._
|
||||||
|
*/
|
||||||
|
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
|
||||||
|
return functionCall(target, data, "Address: low-level call failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
|
||||||
|
* `errorMessage` as a fallback revert reason when `target` reverts.
|
||||||
|
*
|
||||||
|
* _Available since v3.1._
|
||||||
|
*/
|
||||||
|
function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {
|
||||||
|
return functionCallWithValue(target, data, 0, errorMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
|
||||||
|
* but also transferring `value` wei to `target`.
|
||||||
|
*
|
||||||
|
* Requirements:
|
||||||
|
*
|
||||||
|
* - the calling contract must have an ETH balance of at least `value`.
|
||||||
|
* - the called Solidity function must be `payable`.
|
||||||
|
*
|
||||||
|
* _Available since v3.1._
|
||||||
|
*/
|
||||||
|
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");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
|
||||||
|
* with `errorMessage` as a fallback revert reason when `target` reverts.
|
||||||
|
*
|
||||||
|
* _Available since v3.1._
|
||||||
|
*/
|
||||||
|
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");
|
||||||
|
|
||||||
|
// solhint-disable-next-line avoid-low-level-calls
|
||||||
|
(bool success, bytes memory returndata) = target.call{ value: value }(data);
|
||||||
|
return _verifyCallResult(success, returndata, errorMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
|
||||||
|
* but performing a static call.
|
||||||
|
*
|
||||||
|
* _Available since v3.3._
|
||||||
|
*/
|
||||||
|
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
|
||||||
|
return functionStaticCall(target, data, "Address: low-level static call failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
|
||||||
|
* but performing a static call.
|
||||||
|
*
|
||||||
|
* _Available since v3.3._
|
||||||
|
*/
|
||||||
|
function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {
|
||||||
|
require(isContract(target), "Address: static call to non-contract");
|
||||||
|
|
||||||
|
// solhint-disable-next-line avoid-low-level-calls
|
||||||
|
(bool success, bytes memory returndata) = target.staticcall(data);
|
||||||
|
return _verifyCallResult(success, returndata, errorMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
|
||||||
|
* but performing a delegate call.
|
||||||
|
*
|
||||||
|
* _Available since v3.4._
|
||||||
|
*/
|
||||||
|
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
|
||||||
|
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
|
||||||
|
* but performing a delegate call.
|
||||||
|
*
|
||||||
|
* _Available since v3.4._
|
||||||
|
*/
|
||||||
|
function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {
|
||||||
|
require(isContract(target), "Address: delegate call to non-contract");
|
||||||
|
|
||||||
|
// solhint-disable-next-line avoid-low-level-calls
|
||||||
|
(bool success, bytes memory returndata) = target.delegatecall(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 {
|
||||||
|
// Look for revert reason and bubble it up if present
|
||||||
|
if (returndata.length > 0) {
|
||||||
|
// The easiest way to bubble the revert reason is using memory via assembly
|
||||||
|
|
||||||
|
// solhint-disable-next-line no-inline-assembly
|
||||||
|
assembly {
|
||||||
|
let returndata_size := mload(returndata)
|
||||||
|
revert(add(32, returndata), returndata_size)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
revert(errorMessage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
68
contracts/lib/Strings.sol
Normal file
68
contracts/lib/Strings.sol
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
// This is a file copied from https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/Strings.sol
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
pragma solidity 0.6.9;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dev String operations.
|
||||||
|
*/
|
||||||
|
library Strings {
|
||||||
|
bytes16 private constant alphabet = "0123456789abcdef";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dev Converts a `uint256` to its ASCII `string` decimal representation.
|
||||||
|
*/
|
||||||
|
function toString(uint256 value) internal pure returns (string memory) {
|
||||||
|
// Inspired by OraclizeAPI's implementation - MIT licence
|
||||||
|
// https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol
|
||||||
|
|
||||||
|
if (value == 0) {
|
||||||
|
return "0";
|
||||||
|
}
|
||||||
|
uint256 temp = value;
|
||||||
|
uint256 digits;
|
||||||
|
while (temp != 0) {
|
||||||
|
digits++;
|
||||||
|
temp /= 10;
|
||||||
|
}
|
||||||
|
bytes memory buffer = new bytes(digits);
|
||||||
|
while (value != 0) {
|
||||||
|
digits -= 1;
|
||||||
|
buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));
|
||||||
|
value /= 10;
|
||||||
|
}
|
||||||
|
return string(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
|
||||||
|
*/
|
||||||
|
function toHexString(uint256 value) internal pure returns (string memory) {
|
||||||
|
if (value == 0) {
|
||||||
|
return "0x00";
|
||||||
|
}
|
||||||
|
uint256 temp = value;
|
||||||
|
uint256 length = 0;
|
||||||
|
while (temp != 0) {
|
||||||
|
length++;
|
||||||
|
temp >>= 8;
|
||||||
|
}
|
||||||
|
return toHexString(value, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.
|
||||||
|
*/
|
||||||
|
function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
|
||||||
|
bytes memory buffer = new bytes(2 * length + 2);
|
||||||
|
buffer[0] = "0";
|
||||||
|
buffer[1] = "x";
|
||||||
|
for (uint256 i = 2 * length + 1; i > 1; --i) {
|
||||||
|
buffer[i] = alphabet[value & 0xf];
|
||||||
|
value >>= 4;
|
||||||
|
}
|
||||||
|
require(value == 0, "Strings: hex length insufficient");
|
||||||
|
return string(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -40,6 +40,7 @@ module.exports = async (deployer, network, accounts) => {
|
|||||||
let WETHAddress = CONFIG.WETH;
|
let WETHAddress = CONFIG.WETH;
|
||||||
let DODOTokenAddress = CONFIG.DODO;
|
let DODOTokenAddress = CONFIG.DODO;
|
||||||
let DODOApproveProxyAddress = CONFIG.DODOApproveProxy;
|
let DODOApproveProxyAddress = CONFIG.DODOApproveProxy;
|
||||||
|
let WETH = CONFIG.WETH;
|
||||||
|
|
||||||
let DspTemplateAddress = CONFIG.DSP;
|
let DspTemplateAddress = CONFIG.DSP;
|
||||||
let DspFactoryAddress = CONFIG.DSPFactory;
|
let DspFactoryAddress = CONFIG.DSPFactory;
|
||||||
|
|||||||
Reference in New Issue
Block a user