编译器
0.8.19+commit.7dd6d404
文件 1 的 19: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 的 19: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 的 19:DexfaiINFT.sol
pragma solidity ^0.8.19;
import "DexfaiPool.sol";
import "ERC721Enumerable.sol";
import "IDexfaiINFT.sol";
import "IERC20.sol";
import "IDexfaiFactory.sol";
import "IWETH.sol";
contract DexfaiINFT is IDexfaiINFT, ERC721Enumerable {
address private WETH;
address private underlyingToken;
address private dexfaiFactory;
string private baseURI;
uint private counter;
uint public override reserve;
uint public override totalSharesIssued;
uint public override initialReserve;
uint private constant NOT_ENTERED = 1;
uint private constant ENTERED = 2;
uint private status;
uint private expectedMints;
mapping(address => uint) public override harvestedBalance;
mapping(uint => uint) public override INFTShares;
mapping(address => mapping(uint => uint)) public override sharesHarvestedByPool;
mapping(address => uint) public override totalSharesHarvestedByPool;
modifier onlyOwner() {
require(msg.sender == IDexfaiFactory(dexfaiFactory).getOwner(), 'DexfaiINFT: NOT_OWNER');
_;
}
modifier lock() {
require(status != ENTERED, 'DexfaiINFT: REENTRANT_CALL');
status = ENTERED;
_;
status = NOT_ENTERED;
}
constructor(
address _dexfaiFactory,
address _WETH,
address _underlyingToken,
uint _initialReserve,
uint _expectedMints
) ERC721('Infinity-NFT', 'INFT') {
status = NOT_ENTERED;
dexfaiFactory = _dexfaiFactory;
WETH = _WETH;
underlyingToken = _underlyingToken;
initialReserve = _initialReserve;
expectedMints = _expectedMints;
totalSharesIssued = 1;
}
receive() external payable {
assert(msg.sender == WETH);
}
function premint(
address[] memory _legacyLNFTHolders,
uint[] memory _initialShares
) external override onlyOwner {
require(counter < expectedMints, 'DexfaiINFT: PREMINTS_ENDED');
require(_initialShares.length == _legacyLNFTHolders.length, 'DexfaiINFT: INVALID_VALUES');
for (uint i = 0; i < _initialShares.length; i++) {
counter += 1;
_safeMint(_legacyLNFTHolders[i], counter);
INFTShares[counter] = _initialShares[i];
totalSharesIssued += _initialShares[i];
}
}
function setBaseURI(string memory _newBaseURI) external override onlyOwner {
baseURI = _newBaseURI;
}
function _baseURI() internal view override returns (string memory) {
return baseURI;
}
function getStates() external view override returns (uint, uint, uint) {
return (initialReserve, reserve, totalSharesIssued);
}
function shareToTokenAmount(
uint _tokenID,
address _token
) external view override returns (uint share2amount, uint inftShare, uint harvestedShares) {
inftShare = INFTShares[_tokenID];
harvestedShares = sharesHarvestedByPool[_token][_tokenID];
uint tokenBalance = IERC20(_token).balanceOf(address(this));
uint share = inftShare - harvestedShares;
uint totalShare = totalSharesIssued - totalSharesHarvestedByPool[_token];
share2amount = (tokenBalance * share) / totalShare;
}
function mint(address _to) external override lock returns (uint tokenID, uint share) {
require(counter >= expectedMints, 'DexfaiINFT: PREMINTS_ONGOING');
uint amount = IERC20(underlyingToken).balanceOf(dexfaiFactory) - reserve;
require(amount != 0, 'DexfaiINFT: INSUFICIENT_AMOUNT');
counter += 1;
tokenID = counter;
reserve += amount;
share = (1e18 * amount) / (reserve + initialReserve);
INFTShares[tokenID] = share;
totalSharesIssued += share;
_safeMint(_to, tokenID);
emit Mint(msg.sender, _to, share, tokenID);
}
function boost(uint _tokenID) external override lock returns (uint share) {
require(_tokenID <= counter, 'DexfaiINFT: Inexistent_ID');
uint amount = IERC20(underlyingToken).balanceOf(dexfaiFactory) - reserve;
require(amount != 0, 'DexfaiINFT: INSUFICIENT_AMOUNT');
reserve += amount;
share = (1e18 * amount) / (reserve + initialReserve);
INFTShares[_tokenID] += share;
totalSharesIssued += share;
emit Boost(msg.sender, share, _tokenID);
}
function _harvest(
address _token,
uint _tokenID,
uint _amount
) private returns (uint harvestedTokenShare) {
require(ownerOf(_tokenID) == msg.sender, 'DexfaiINFT: NOT_INFT_OWNER');
uint tokenBalance = IERC20(_token).balanceOf(address(this));
uint share = INFTShares[_tokenID] - sharesHarvestedByPool[_token][_tokenID];
uint totalShare = totalSharesIssued - totalSharesHarvestedByPool[_token];
uint share2amount = (tokenBalance * share) / totalShare;
require(_amount <= share2amount, 'DexfaiINFT: AMOUNT_EXCEEDS_SHARE');
harvestedTokenShare = (share * _amount) / share2amount;
sharesHarvestedByPool[_token][_tokenID] += harvestedTokenShare;
totalSharesHarvestedByPool[_token] += harvestedTokenShare;
harvestedBalance[_token] += _amount;
}
function harvestToken(
address _token,
uint _tokenID,
uint _amount
) external override lock returns (uint) {
uint harvestedTokenShare = _harvest(_token, _tokenID, _amount);
_safeTransfer(_token, ownerOf(_tokenID), _amount);
emit HarvestToken(_token, _amount, harvestedTokenShare, _tokenID);
return _amount;
}
function harvestETH(uint _tokenID, uint _amount) external override lock returns (uint) {
uint harvestedTokenShare = _harvest(WETH, _tokenID, _amount);
IWETH(WETH).withdraw(_amount);
_safeTransferETH(ownerOf(_tokenID), _amount);
emit HarvestETH(_amount, harvestedTokenShare, _tokenID);
return _amount;
}
function _safeTransfer(address _token, address _to, uint256 _value) internal {
require(_token.code.length > 0, 'DexfaiINFT: TRANSFER_FAILED');
(bool success, bytes memory data) = _token.call(
abi.encodeWithSelector(IERC20.transfer.selector, _to, _value)
);
require(
success && (data.length == 0 || abi.decode(data, (bool))),
'DexfaiINFT: TRANSFER_FAILED'
);
}
function _safeTransferETH(address _to, uint _value) internal {
(bool success, ) = _to.call{value: _value}(new bytes(0));
require(success, 'DexfaiINFT: ETH_TRANSFER_FAILED');
}
}
文件 4 的 19:DexfaiPool.sol
pragma solidity ^0.8.19;
import "IDexfaiPool.sol";
import "IERC20.sol";
import "IDexfaiFactory.sol";
contract DexfaiPool is IDexfaiPool {
string public override name;
string public override symbol;
uint8 public constant override decimals = 18;
struct Observation {
uint rCumulative;
uint wCumulative;
uint timestamp;
}
uint private constant PERIOD_SIZE = 900;
uint private constant RING_SIZE = 672;
uint public ringBufferNonce = 0;
Observation[RING_SIZE] public override observations;
uint private r;
uint private w;
uint private blockTimestampLast;
uint private rCumulativeLast;
uint private wCumulativeLast;
uint public override totalSupply = 0;
uint private seeded = 1;
IDexfaiFactory private dexfaiFactory;
address public override poolToken;
bytes32 public override DOMAIN_SEPARATOR;
bytes32 public constant override PERMIT_TYPEHASH =
0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9;
mapping(address => uint) public override nonces;
mapping(address => mapping(address => uint)) public override allowance;
mapping(address => uint) public override balanceOf;
modifier linked() {
address core = getDexfaiCore();
require(msg.sender == core, 'DexfaiPool: NOT_CORE');
_;
}
constructor() {
write(0, 0, block.timestamp);
DOMAIN_SEPARATOR = keccak256(
abi.encode(
keccak256(
'EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)'
),
keccak256(bytes(name)),
keccak256('1'),
block.chainid,
address(this)
)
);
}
function getCurrentIndex() public view override returns (uint16 index) {
index = uint16(ringBufferNonce % RING_SIZE);
}
function write(uint _r, uint _w, uint _blockTimestamp) private returns (uint16 index) {
index = getCurrentIndex();
observations[index] = Observation(_r, _w, _blockTimestamp);
ringBufferNonce += 1;
emit Write(_r, _w, _blockTimestamp);
}
function getNthObservation(
uint _n
) public view override returns (uint rCumulative, uint wCumulative, uint timestamp) {
require(ringBufferNonce >= _n, 'DexfaiPool: INEXISTENT_HISTORY');
require(_n < RING_SIZE, 'DexfaiPool: OVERRIDDEN_HISTORY');
uint16 index = uint16((ringBufferNonce - _n) % RING_SIZE);
Observation memory point = observations[index];
rCumulative = point.rCumulative;
wCumulative = point.wCumulative;
timestamp = point.timestamp;
}
function getCumulativeLast() public view override returns (uint, uint, uint) {
return (rCumulativeLast, wCumulativeLast, blockTimestampLast);
}
function initialize(address _token, address _dexfaiFactory) external override {
require(seeded == 1, 'DexfaiPool: DEX_SEEDED');
poolToken = _token;
dexfaiFactory = IDexfaiFactory(_dexfaiFactory);
name = string(abi.encodePacked(IERC20(_token).name(), '-Xfai'));
symbol = string(abi.encodePacked(IERC20(_token).symbol(), '-Xfai'));
seeded = 2;
}
function getDexfaiCore() public view override returns (address) {
return dexfaiFactory.getDexfaiCore();
}
function getStates() external view override returns (uint, uint, uint) {
return (r, w, blockTimestampLast);
}
function update(uint _balance, uint _r, uint _w) external override linked {
uint blockTimestamp = block.timestamp;
uint timeElapsed = blockTimestamp - blockTimestampLast;
if (timeElapsed > 0 && _r != 0) {
unchecked {
rCumulativeLast += _r * timeElapsed;
wCumulativeLast += _w * timeElapsed;
}
}
(, , uint timestamp) = getNthObservation(1);
timeElapsed = blockTimestamp - timestamp;
if (timeElapsed > PERIOD_SIZE && _r != 0) {
write(rCumulativeLast, wCumulativeLast, blockTimestamp);
}
r = _balance;
w = _w;
blockTimestampLast = blockTimestamp;
emit Sync(_balance, _w);
}
function safeTransfer(address _token, address _to, uint256 _value) external override linked {
require(_token.code.length > 0, 'DexfaiPool: TRANSFER_FAILED');
(bool success, bytes memory data) = _token.call(
abi.encodeWithSelector(IERC20.transfer.selector, _to, _value)
);
require(
success && (data.length == 0 || abi.decode(data, (bool))),
'DexfaiPool: TRANSFER_FAILED'
);
}
function mint(address _to, uint _amount) public override linked {
_mint(_to, _amount);
}
function burn(address _to, uint _amount) public override linked {
_burn(_to, _amount);
}
function _mint(address _dst, uint _amount) internal {
totalSupply += _amount;
balanceOf[_dst] += _amount;
emit Transfer(address(0), _dst, _amount);
}
function _burn(address _dst, uint _amount) internal {
totalSupply -= _amount;
balanceOf[_dst] -= _amount;
emit Transfer(_dst, address(0), _amount);
}
function approve(address _spender, uint _amount) external override returns (bool) {
allowance[msg.sender][_spender] = _amount;
emit Approval(msg.sender, _spender, _amount);
return true;
}
function permit(
address _owner,
address _spender,
uint _value,
uint _deadline,
uint8 _v,
bytes32 _r,
bytes32 _s
) external override {
require(_deadline >= block.timestamp, 'DexfaiPool: EXPIRED');
bytes32 digest = keccak256(
abi.encodePacked(
'\x19\x01',
DOMAIN_SEPARATOR,
keccak256(
abi.encode(PERMIT_TYPEHASH, _owner, _spender, _value, nonces[_owner]++, _deadline)
)
)
);
address recoveredAddress = ecrecover(digest, _v, _r, _s);
require(recoveredAddress != address(0), 'DexfaiPool: INVALID_SIGNATURE');
require(recoveredAddress == _owner, 'DexfaiPool: INVALID_SIGNATURE');
allowance[_owner][_spender] = _value;
emit Approval(_owner, _spender, _value);
}
function transfer(address _dst, uint _amount) external override returns (bool) {
_transferTokens(msg.sender, _dst, _amount);
return true;
}
function transferFrom(address _src, address _dst, uint _amount) external override returns (bool) {
address spender = msg.sender;
uint spenderAllowance = allowance[_src][spender];
if (spender != _src && spenderAllowance != type(uint).max) {
uint newAllowance = spenderAllowance - _amount;
allowance[_src][spender] = newAllowance;
emit Approval(_src, spender, newAllowance);
}
_transferTokens(_src, _dst, _amount);
return true;
}
function _transferTokens(address _src, address _dst, uint _amount) internal {
balanceOf[_src] -= _amount;
balanceOf[_dst] += _amount;
emit Transfer(_src, _dst, _amount);
}
}
文件 5 的 19:ERC165.sol
pragma solidity ^0.8.0;
import "IERC165.sol";
abstract contract ERC165 is IERC165 {
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IERC165).interfaceId;
}
}
文件 6 的 19:ERC721.sol
pragma solidity ^0.8.0;
import "IERC721.sol";
import "IERC721Receiver.sol";
import "IERC721Metadata.sol";
import "Address.sol";
import "Context.sol";
import "Strings.sol";
import "ERC165.sol";
contract ERC721 is Context, ERC165, IERC721, IERC721Metadata {
using Address for address;
using Strings for uint256;
string private _name;
string private _symbol;
mapping(uint256 => address) private _owners;
mapping(address => uint256) private _balances;
mapping(uint256 => address) private _tokenApprovals;
mapping(address => mapping(address => bool)) private _operatorApprovals;
constructor(string memory name_, string memory symbol_) {
_name = name_;
_symbol = symbol_;
}
function supportsInterface(
bytes4 interfaceId
) public view virtual override(ERC165, IERC165) returns (bool) {
return
interfaceId == type(IERC721).interfaceId ||
interfaceId == type(IERC721Metadata).interfaceId ||
super.supportsInterface(interfaceId);
}
function balanceOf(address owner) public view virtual override returns (uint256) {
require(owner != address(0), 'ERC721: address zero is not a valid owner');
return _balances[owner];
}
function ownerOf(uint256 tokenId) public view virtual override returns (address) {
address owner = _ownerOf(tokenId);
require(owner != address(0), 'ERC721: invalid token ID');
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 tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
_requireMinted(tokenId);
string memory baseURI = _baseURI();
return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : '';
}
function _baseURI() internal view virtual returns (string memory) {
return '';
}
function approve(address to, uint256 tokenId) public virtual override {
address owner = ERC721.ownerOf(tokenId);
require(to != owner, 'ERC721: approval to current owner');
require(
_msgSender() == owner || isApprovedForAll(owner, _msgSender()),
'ERC721: approve caller is not token owner or approved for all'
);
_approve(to, tokenId);
}
function getApproved(uint256 tokenId) public view virtual override returns (address) {
_requireMinted(tokenId);
return _tokenApprovals[tokenId];
}
function setApprovalForAll(address operator, bool approved) public virtual override {
_setApprovalForAll(_msgSender(), 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 {
require(
_isApprovedOrOwner(_msgSender(), tokenId),
'ERC721: caller is not token owner or 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(_msgSender(), tokenId),
'ERC721: caller is not token owner or approved'
);
_safeTransfer(from, to, tokenId, data);
}
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 _ownerOf(uint256 tokenId) internal view virtual returns (address) {
return _owners[tokenId];
}
function _exists(uint256 tokenId) internal view virtual returns (bool) {
return _ownerOf(tokenId) != address(0);
}
function _isApprovedOrOwner(
address spender,
uint256 tokenId
) internal view virtual returns (bool) {
address owner = ERC721.ownerOf(tokenId);
return (spender == owner ||
isApprovedForAll(owner, spender) ||
getApproved(tokenId) == 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, 1);
require(!_exists(tokenId), 'ERC721: token already minted');
unchecked {
_balances[to] += 1;
}
_owners[tokenId] = to;
emit Transfer(address(0), to, tokenId);
_afterTokenTransfer(address(0), to, tokenId, 1);
}
function _burn(uint256 tokenId) internal virtual {
address owner = ERC721.ownerOf(tokenId);
_beforeTokenTransfer(owner, address(0), tokenId, 1);
owner = ERC721.ownerOf(tokenId);
delete _tokenApprovals[tokenId];
unchecked {
_balances[owner] -= 1;
}
delete _owners[tokenId];
emit Transfer(owner, address(0), tokenId);
_afterTokenTransfer(owner, address(0), tokenId, 1);
}
function _transfer(address from, address to, uint256 tokenId) internal virtual {
require(ERC721.ownerOf(tokenId) == from, 'ERC721: transfer from incorrect owner');
require(to != address(0), 'ERC721: transfer to the zero address');
_beforeTokenTransfer(from, to, tokenId, 1);
require(ERC721.ownerOf(tokenId) == from, 'ERC721: transfer from incorrect owner');
delete _tokenApprovals[tokenId];
unchecked {
_balances[from] -= 1;
_balances[to] += 1;
}
_owners[tokenId] = to;
emit Transfer(from, to, tokenId);
_afterTokenTransfer(from, to, tokenId, 1);
}
function _approve(address to, uint256 tokenId) internal virtual {
_tokenApprovals[tokenId] = to;
emit Approval(ERC721.ownerOf(tokenId), to, tokenId);
}
function _setApprovalForAll(address owner, address operator, bool approved) internal virtual {
require(owner != operator, 'ERC721: approve to caller');
_operatorApprovals[owner][operator] = approved;
emit ApprovalForAll(owner, operator, approved);
}
function _requireMinted(uint256 tokenId) internal view virtual {
require(_exists(tokenId), 'ERC721: invalid token ID');
}
function _checkOnERC721Received(
address from,
address to,
uint256 tokenId,
bytes memory data
) private returns (bool) {
if (to.isContract()) {
try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (
bytes4 retval
) {
return retval == IERC721Receiver.onERC721Received.selector;
} catch (bytes memory reason) {
if (reason.length == 0) {
revert('ERC721: transfer to non ERC721Receiver implementer');
} else {
assembly {
revert(add(32, reason), mload(reason))
}
}
}
} else {
return true;
}
}
function _beforeTokenTransfer(
address from,
address to,
uint256 ,
uint256 batchSize
) internal virtual {
if (batchSize > 1) {
if (from != address(0)) {
_balances[from] -= batchSize;
}
if (to != address(0)) {
_balances[to] += batchSize;
}
}
}
function _afterTokenTransfer(
address from,
address to,
uint256 firstTokenId,
uint256 batchSize
) internal virtual {}
}
文件 7 的 19:ERC721Enumerable.sol
pragma solidity ^0.8.0;
import "ERC721.sol";
import "IERC721Enumerable.sol";
abstract contract ERC721Enumerable is ERC721, IERC721Enumerable {
mapping(address => mapping(uint256 => uint256)) private _ownedTokens;
mapping(uint256 => uint256) private _ownedTokensIndex;
uint256[] private _allTokens;
mapping(uint256 => uint256) private _allTokensIndex;
function supportsInterface(
bytes4 interfaceId
) public view virtual override(IERC165, ERC721) returns (bool) {
return
interfaceId == type(IERC721Enumerable).interfaceId || super.supportsInterface(interfaceId);
}
function tokenOfOwnerByIndex(
address owner,
uint256 index
) public view virtual override returns (uint256) {
require(index < ERC721.balanceOf(owner), 'ERC721Enumerable: owner index out of bounds');
return _ownedTokens[owner][index];
}
function totalSupply() public view virtual override returns (uint256) {
return _allTokens.length;
}
function tokenByIndex(uint256 index) public view virtual override returns (uint256) {
require(index < ERC721Enumerable.totalSupply(), 'ERC721Enumerable: global index out of bounds');
return _allTokens[index];
}
function _beforeTokenTransfer(
address from,
address to,
uint256 firstTokenId,
uint256 batchSize
) internal virtual override {
super._beforeTokenTransfer(from, to, firstTokenId, batchSize);
if (batchSize > 1) {
revert('ERC721Enumerable: consecutive transfers not supported');
}
uint256 tokenId = firstTokenId;
if (from == address(0)) {
_addTokenToAllTokensEnumeration(tokenId);
} else if (from != to) {
_removeTokenFromOwnerEnumeration(from, tokenId);
}
if (to == address(0)) {
_removeTokenFromAllTokensEnumeration(tokenId);
} else if (to != from) {
_addTokenToOwnerEnumeration(to, tokenId);
}
}
function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private {
uint256 length = ERC721.balanceOf(to);
_ownedTokens[to][length] = tokenId;
_ownedTokensIndex[tokenId] = length;
}
function _addTokenToAllTokensEnumeration(uint256 tokenId) private {
_allTokensIndex[tokenId] = _allTokens.length;
_allTokens.push(tokenId);
}
function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private {
uint256 lastTokenIndex = ERC721.balanceOf(from) - 1;
uint256 tokenIndex = _ownedTokensIndex[tokenId];
if (tokenIndex != lastTokenIndex) {
uint256 lastTokenId = _ownedTokens[from][lastTokenIndex];
_ownedTokens[from][tokenIndex] = lastTokenId;
_ownedTokensIndex[lastTokenId] = tokenIndex;
}
delete _ownedTokensIndex[tokenId];
delete _ownedTokens[from][lastTokenIndex];
}
function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private {
uint256 lastTokenIndex = _allTokens.length - 1;
uint256 tokenIndex = _allTokensIndex[tokenId];
uint256 lastTokenId = _allTokens[lastTokenIndex];
_allTokens[tokenIndex] = lastTokenId;
_allTokensIndex[lastTokenId] = tokenIndex;
delete _allTokensIndex[tokenId];
_allTokens.pop();
}
}
文件 8 的 19:IDexfaiFactory.sol
pragma solidity ^0.8.19;
interface IDexfaiFactory {
function getPool(address _token) external view returns (address pool);
function allPools(uint256) external view returns (address pool);
function poolCodeHash() external pure returns (bytes32);
function allPoolsLength() external view returns (uint);
function createPool(address _token) external returns (address pool);
function setDexfaiCore(address _core) external;
function getDexfaiCore() external view returns (address);
function setOwner(address _owner) external;
function setWhitelistingPhase(bool _state) external;
function getOwner() external view returns (address);
event ChangedOwner(address indexed owner);
event ChangedCore(address indexed core);
event Whitelisting(bool state);
event PoolCreated(address indexed token, address indexed pool, uint allPoolsSize);
}
文件 9 的 19:IDexfaiINFT.sol
pragma solidity ^0.8.19;
interface IDexfaiINFT {
function reserve() external view returns (uint);
function totalSharesIssued() external view returns (uint);
function initialReserve() external view returns (uint);
function harvestedBalance(address _token) external view returns (uint);
function INFTShares(uint _id) external view returns (uint);
function sharesHarvestedByPool(address _token, uint _id) external view returns (uint);
function totalSharesHarvestedByPool(address _token) external view returns (uint);
function setBaseURI(string memory _baseURI) external;
function getStates() external view returns (uint, uint, uint);
function shareToTokenAmount(
uint _tokenID,
address _token
) external view returns (uint share2amount, uint inftShare, uint harvestedShares);
function premint(address[] memory _legacyLNFTHolders, uint[] memory _initialShares) external;
function mint(address _to) external returns (uint tokenID, uint share);
function boost(uint _tokenID) external returns (uint share);
function harvestToken(address _token, uint _tokenID, uint _amount) external returns (uint);
function harvestETH(uint _tokenID, uint _amount) external returns (uint);
event Mint(address indexed from, address indexed to, uint share, uint id);
event Boost(address indexed from, uint share, uint id);
event HarvestToken(address token, uint harvestedAmount, uint harvestedShare, uint id);
event HarvestETH(uint harvestedAmount, uint harvestedShare, uint id);
}
文件 10 的 19:IDexfaiPool.sol
pragma solidity ^0.8.19;
interface IDexfaiPool {
function getCurrentIndex() external view returns (uint16 index);
function getNthObservation(
uint _n
) external view returns (uint timestamp, uint rCumulative, uint wCumulative);
function getCumulativeLast()
external
view
returns (uint timestamp, uint rCumulative, uint wCumulative);
function ringBufferNonce() external view returns (uint);
function observations(uint observation) external view returns (uint, uint, uint);
function getDexfaiCore() external view returns (address);
function poolToken() external view returns (address);
function initialize(address _token, address _dexfaiFactory) external;
function getStates() external view returns (uint, uint, uint);
function update(uint _balance, uint _r, uint _w) external;
function mint(address _to, uint _amount) external;
function burn(address _to, uint _amount) external;
function safeTransfer(address _token, address _to, uint256 _value) external;
function totalSupply() external view returns (uint);
function transfer(address _recipient, uint _amount) external returns (bool);
function decimals() external view returns (uint8);
function balanceOf(address) external view returns (uint);
function transferFrom(address _sender, address _recipient, uint _amount) external returns (bool);
function approve(address _spender, uint _value) external returns (bool);
function allowance(address _owner, address _spender) external view returns (uint256);
function symbol() external view returns (string memory);
function name() external view returns (string memory);
function permit(
address _owner,
address _spender,
uint _value,
uint _deadline,
uint8 _v,
bytes32 _re,
bytes32 _s
) external;
function nonces(address _owner) external view returns (uint);
function PERMIT_TYPEHASH() external view returns (bytes32);
function DOMAIN_SEPARATOR() external view returns (bytes32);
event Sync(uint _reserve, uint _w);
event Transfer(address indexed _from, address indexed _to, uint _amount);
event Approval(address indexed _owner, address indexed _spender, uint _amount);
event Write(uint _r, uint _w, uint _blockTimestamp);
}
文件 11 的 19:IERC165.sol
pragma solidity ^0.8.19;
interface IERC165 {
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
文件 12 的 19:IERC20.sol
pragma solidity ^0.8.19;
interface IERC20 {
function totalSupply() external view returns (uint);
function transfer(address recipient, uint amount) external returns (bool);
function decimals() external view returns (uint8);
function balanceOf(address) external view returns (uint);
function transferFrom(address sender, address recipient, uint amount) external returns (bool);
function approve(address spender, uint value) external returns (bool);
function allowance(address owner, address spender) external view returns (uint256);
function symbol() external view returns (string memory);
function name() external view returns (string memory);
}
文件 13 的 19:IERC721.sol
pragma solidity ^0.8.19;
import "IERC165.sol";
interface IERC721 is IERC165 {
event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
function balanceOf(address owner) external view returns (uint256 balance);
function ownerOf(uint256 tokenId) external view returns (address owner);
function safeTransferFrom(
address from,
address to,
uint256 tokenId,
bytes calldata data
) external;
function safeTransferFrom(address from, address to, uint256 tokenId) external;
function transferFrom(address from, address to, uint256 tokenId) external;
function approve(address to, uint256 tokenId) external;
function setApprovalForAll(address operator, bool _approved) external;
function getApproved(uint256 tokenId) external view returns (address operator);
function isApprovedForAll(address owner, address operator) external view returns (bool);
}
文件 14 的 19:IERC721Enumerable.sol
pragma solidity ^0.8.19;
import "IERC721.sol";
interface IERC721Enumerable is IERC721 {
function totalSupply() external view returns (uint256);
function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256);
function tokenByIndex(uint256 index) external view returns (uint256);
}
文件 15 的 19:IERC721Metadata.sol
pragma solidity ^0.8.19;
import "IERC721.sol";
interface IERC721Metadata is IERC721 {
function name() external view returns (string memory);
function symbol() external view returns (string memory);
function tokenURI(uint256 tokenId) external view returns (string memory);
}
文件 16 的 19:IERC721Receiver.sol
pragma solidity ^0.8.19;
interface IERC721Receiver {
function onERC721Received(
address operator,
address from,
uint256 tokenId,
bytes calldata data
) external returns (bytes4);
}
文件 17 的 19:IWETH.sol
pragma solidity ^0.8.19;
interface IWETH {
function deposit() external payable;
function transfer(address to, uint value) external returns (bool);
function withdraw(uint) external;
}
文件 18 的 19:OZMath.sol
pragma solidity ^0.8.0;
library OZMath {
enum Rounding {
Down,
Up,
Zero
}
function log10(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >= 10 ** 64) {
value /= 10 ** 64;
result += 64;
}
if (value >= 10 ** 32) {
value /= 10 ** 32;
result += 32;
}
if (value >= 10 ** 16) {
value /= 10 ** 16;
result += 16;
}
if (value >= 10 ** 8) {
value /= 10 ** 8;
result += 8;
}
if (value >= 10 ** 4) {
value /= 10 ** 4;
result += 4;
}
if (value >= 10 ** 2) {
value /= 10 ** 2;
result += 2;
}
if (value >= 10 ** 1) {
result += 1;
}
}
return result;
}
function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log10(value);
return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);
}
}
function log256(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >> 128 > 0) {
value >>= 128;
result += 16;
}
if (value >> 64 > 0) {
value >>= 64;
result += 8;
}
if (value >> 32 > 0) {
value >>= 32;
result += 4;
}
if (value >> 16 > 0) {
value >>= 16;
result += 2;
}
if (value >> 8 > 0) {
result += 1;
}
}
return result;
}
function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log256(value);
return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);
}
}
}
文件 19 的 19:Strings.sol
pragma solidity ^0.8.0;
import "OZMath.sol";
library Strings {
bytes16 private constant _SYMBOLS = '0123456789abcdef';
uint8 private constant _ADDRESS_LENGTH = 20;
function toString(uint256 value) internal pure returns (string memory) {
unchecked {
uint256 length = OZMath.log10(value) + 1;
string memory buffer = new string(length);
uint256 ptr;
assembly {
ptr := add(buffer, add(32, length))
}
while (true) {
ptr--;
assembly {
mstore8(ptr, byte(mod(value, 10), _SYMBOLS))
}
value /= 10;
if (value == 0) break;
}
return buffer;
}
}
function toHexString(uint256 value) internal pure returns (string memory) {
unchecked {
return toHexString(value, OZMath.log256(value) + 1);
}
}
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] = _SYMBOLS[value & 0xf];
value >>= 4;
}
require(value == 0, 'Strings: hex length insufficient');
return string(buffer);
}
function toHexString(address addr) internal pure returns (string memory) {
return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);
}
}
{
"compilationTarget": {
"DexfaiINFT.sol": "DexfaiINFT"
},
"evmVersion": "london",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": []
}
[{"inputs":[{"internalType":"address","name":"_dexfaiFactory","type":"address"},{"internalType":"address","name":"_WETH","type":"address"},{"internalType":"address","name":"_underlyingToken","type":"address"},{"internalType":"uint256","name":"_initialReserve","type":"uint256"},{"internalType":"uint256","name":"_expectedMints","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint256","name":"share","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"}],"name":"Boost","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"harvestedAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"harvestedShare","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"}],"name":"HarvestETH","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"harvestedAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"harvestedShare","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"}],"name":"HarvestToken","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"share","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"}],"name":"Mint","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"INFTShares","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenID","type":"uint256"}],"name":"boost","outputs":[{"internalType":"uint256","name":"share","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getStates","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenID","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"harvestETH","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_tokenID","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"harvestToken","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"harvestedBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"initialReserve","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"}],"name":"mint","outputs":[{"internalType":"uint256","name":"tokenID","type":"uint256"},{"internalType":"uint256","name":"share","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"_legacyLNFTHolders","type":"address[]"},{"internalType":"uint256[]","name":"_initialShares","type":"uint256[]"}],"name":"premint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"reserve","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_newBaseURI","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenID","type":"uint256"},{"internalType":"address","name":"_token","type":"address"}],"name":"shareToTokenAmount","outputs":[{"internalType":"uint256","name":"share2amount","type":"uint256"},{"internalType":"uint256","name":"inftShare","type":"uint256"},{"internalType":"uint256","name":"harvestedShares","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"sharesHarvestedByPool","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"totalSharesHarvestedByPool","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSharesIssued","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]