Overview
S Balance
S Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 1 from a total of 1 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Set Aggregator C... | 11034079 | 4 days ago | IN | 0 S | 0.0023891 |
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Name:
DBOFactory
Compiler Version
v0.8.20+commit.a1b79de6
Optimization Enabled:
Yes with 200 runs
Other Settings:
shanghai EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
pragma solidity ^0.8.0; // if NFT --> it has to be a receipt import "@contracts/DebitaBorrowOffer-Implementation.sol"; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import "@contracts/DebitaProxyContract.sol"; contract DBOFactory { event BorrowOrderCreated( address indexed borrowOrder, address indexed owner, uint maxApr, uint duration, uint[] LTVs, uint[] ratios, uint availableAmount, bool isActive ); event BorrowOrderUpdated( address indexed borrowOrder, address indexed owner, uint maxApr, uint duration, uint[] LTVs, uint[] ratios, uint availableAmount, bool isActive ); event BorrowOrderDeleted( address indexed borrowOrder, address indexed owner, uint maxApr, uint duration, uint[] LTVs, uint[] ratios, uint availableAmount, bool isActive ); mapping(address => bool) public isBorrowOrderLegit; mapping(address => uint) public borrowOrderIndex; mapping(uint => address) public allActiveBorrowOrders; uint public activeOrdersCount; address aggregatorContract; address implementationContract; address public owner; constructor(address _implementationContract) { owner = msg.sender; implementationContract = _implementationContract; } modifier onlyBorrowOrder() { require(isBorrowOrderLegit[msg.sender], "Only borrow order"); _; } /** * @dev Creates a new Borrow Order * @param _oraclesActivated Array of booleans that indicates if the oracle is activated por that pair (acceptedPrinciples[i], collateral) * @param _LTVs Array of LTVs for each principle (0 if not accepted) * @param _maxInterestRate Maximum interest rate that the borrower is willing to pay * @param _duration Duration of the loan * @param _acceptedPrinciples Array of addresses of the principles that the borrower is willing to accept * @param _collateral Address of the collateral token * @param _isNFT Boolean that indicates if the collateral is an NFT * @param _receiptID ID of the NFT if the collateral is an NFT * @param _oracleIDS_Principles Array of addresses of the oracles for each principle * @param _ratio Array of ratios for each principle * @param _oracleID_Collateral Address of the oracle for the collateral (used in case oracle is activated) * @param _collateralAmount Amount of collateral willing to be used */ function createBorrowOrder( bool[] memory _oraclesActivated, uint[] memory _LTVs, uint _maxInterestRate, uint _duration, address[] memory _acceptedPrinciples, address _collateral, bool _isNFT, uint _receiptID, address[] memory _oracleIDS_Principles, uint[] memory _ratio, address _oracleID_Collateral, uint _collateralAmount ) external returns (address) { if (_isNFT) { require(_receiptID != 0, "Receipt ID cannot be 0"); require(_collateralAmount == 1, "Started Borrow Amount must be 1"); } require(_LTVs.length == _acceptedPrinciples.length, "Invalid LTVs"); require( _oracleIDS_Principles.length == _acceptedPrinciples.length, "Invalid length" ); require( _oraclesActivated.length == _acceptedPrinciples.length, "Invalid oracles" ); require(_ratio.length == _acceptedPrinciples.length, "Invalid ratio"); require(_collateralAmount > 0, "Invalid started amount"); DebitaProxyContract borrowOfferProxy = new DebitaProxyContract( implementationContract ); DBOImplementation borrowOffer = DBOImplementation( address(borrowOfferProxy) ); borrowOffer.initialize( aggregatorContract, msg.sender, _acceptedPrinciples, _collateral, _oraclesActivated, _isNFT, _LTVs, _maxInterestRate, _duration, _receiptID, _oracleIDS_Principles, _ratio, _oracleID_Collateral, _collateralAmount ); isBorrowOrderLegit[address(borrowOffer)] = true; if (_isNFT) { IERC721(_collateral).transferFrom( msg.sender, address(borrowOffer), _receiptID ); } else { SafeERC20.safeTransferFrom( IERC20(_collateral), msg.sender, address(borrowOffer), _collateralAmount ); } borrowOrderIndex[address(borrowOffer)] = activeOrdersCount; allActiveBorrowOrders[activeOrdersCount] = address(borrowOffer); activeOrdersCount++; uint balance = IERC20(_collateral).balanceOf(address(borrowOffer)); require(balance >= _collateralAmount, "Invalid balance"); emit BorrowOrderCreated( address(borrowOffer), msg.sender, _maxInterestRate, _duration, _LTVs, _ratio, _collateralAmount, true ); return address(borrowOffer); } /** * @dev Deletes Borrow Order from index -- only callable from borrow Orders */ function deleteBorrowOrder(address _borrowOrder) external onlyBorrowOrder { // get index of the borrow order uint index = borrowOrderIndex[_borrowOrder]; borrowOrderIndex[_borrowOrder] = 0; // get last borrow order allActiveBorrowOrders[index] = allActiveBorrowOrders[ activeOrdersCount - 1 ]; // take out last borrow order allActiveBorrowOrders[activeOrdersCount - 1] = address(0); // switch index of the last borrow order to the deleted borrow order borrowOrderIndex[allActiveBorrowOrders[index]] = index; activeOrdersCount--; } function getActiveBorrowOrders( uint offset, uint limit ) external view returns (DBOImplementation.BorrowInfo[] memory) { uint length = limit; if (limit > activeOrdersCount) { length = activeOrdersCount; } // chequear esto DBOImplementation.BorrowInfo[] memory result = new DBOImplementation.BorrowInfo[](length - offset); for (uint i = 0; (i + offset) < length; i++) { address order = allActiveBorrowOrders[offset + i]; DBOImplementation.BorrowInfo memory borrowInfo = DBOImplementation( order ).getBorrowInfo(); result[i] = borrowInfo; } return result; } function setAggregatorContract(address _aggregatorContract) external { require(aggregatorContract == address(0), "Already set"); require(msg.sender == owner, "Only owner can set aggregator contract"); aggregatorContract = _aggregatorContract; } function emitDelete(address _borrowOrder) external onlyBorrowOrder { DBOImplementation borrowOrder = DBOImplementation(_borrowOrder); DBOImplementation.BorrowInfo memory borrowInfo = borrowOrder .getBorrowInfo(); emit BorrowOrderDeleted( _borrowOrder, borrowInfo.owner, borrowInfo.maxApr, borrowInfo.duration, borrowInfo.LTVs, borrowInfo.ratio, borrowInfo.availableAmount, false ); } function emitUpdate(address _borrowOrder) external onlyBorrowOrder { DBOImplementation borrowOrder = DBOImplementation(_borrowOrder); DBOImplementation.BorrowInfo memory borrowInfo = borrowOrder .getBorrowInfo(); emit BorrowOrderUpdated( _borrowOrder, borrowInfo.owner, borrowInfo.maxApr, borrowInfo.duration, borrowInfo.LTVs, borrowInfo.ratio, borrowInfo.availableAmount, borrowOrder.isActive() ); } }
pragma solidity ^0.8.0; import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import "@openzeppelin/contracts/token/ERC721/IERC721.sol"; import "@openzeppelin/contracts/token/ERC721/utils/ERC721Holder.sol"; import "@openzeppelin/contracts/utils/ReentrancyGuard.sol"; import "@openzeppelin/contracts/proxy/utils/Initializable.sol"; interface NFR { struct receiptInstance { uint receiptID; uint attachedNFT; uint lockedAmount; uint lockedDate; uint decimals; address vault; address underlying; } function getDataByReceipt( uint receiptID ) external view returns (receiptInstance memory); } interface IDBOFactory { function emitDelete(address _borrowOrder) external; function emitUpdate(address _borrowOrder) external; function deleteBorrowOrder(address _borrowOrder) external; } contract DBOImplementation is ReentrancyGuard, Initializable { address aggregatorContract; address factoryContract; bool public isActive; uint lastUpdate; using SafeERC20 for IERC20; struct BorrowInfo { address borrowOrderAddress; // address of the borrow order bool[] oraclesPerPairActivated; // oracles activated for each pair uint[] LTVs; // LTVs for each pair uint maxApr; // max APR for the borrow order uint duration; // duration of the borrow order address owner; // owner of the borrow order address[] acceptedPrinciples; // accepted principles for the borrow order address collateral; // collateral for the borrow order address valuableAsset; // ERC721: underlying, ERC20: Same as collateral bool isNFT; // is the collateral an NFT uint receiptID; // receipt ID of the NFT (NFT ID, since we accept only receipt type NFTs) address[] oracles_Principles; // oracles for each principle uint[] ratio; // ratio for each principle address oracle_Collateral; // oracle for the collateral uint valuableAssetAmount; // only used for auction sold NFTs uint availableAmount; // amount of the collateral uint startAmount; // amount of the collateral at the start } BorrowInfo public borrowInformation; modifier onlyOwner() { require(msg.sender == borrowInformation.owner, "Only owner"); _; } modifier onlyAggregator() { require(msg.sender == aggregatorContract, "Only aggregator"); _; } // Prevent the offer from being updated before accepted modifier onlyAfterTimeOut() { require( lastUpdate == 0 || (block.timestamp - lastUpdate) > 1 minutes, "Offer has been updated in the last minute" ); _; } function initialize( address _aggregatorContract, address _owner, address[] memory _acceptedPrinciples, address _collateral, bool[] memory _oraclesActivated, bool _isNFT, uint[] memory _LTVs, uint _maxApr, uint _duration, uint _receiptID, address[] memory _oracleIDS_Principles, uint[] memory _ratio, address _oracleID_Collateral, uint _startedBorrowAmount ) public initializer { aggregatorContract = _aggregatorContract; isActive = true; // seguir aca address _valuableAsset; // if the collateral is an NFT, get the underlying asset if (_isNFT) { NFR.receiptInstance memory nftData = NFR(_collateral) .getDataByReceipt(_receiptID); _startedBorrowAmount = nftData.lockedAmount; _valuableAsset = nftData.underlying; } else { _valuableAsset = _collateral; } borrowInformation = BorrowInfo({ borrowOrderAddress: address(this), oraclesPerPairActivated: _oraclesActivated, LTVs: _LTVs, maxApr: _maxApr, duration: _duration, owner: _owner, acceptedPrinciples: _acceptedPrinciples, collateral: _collateral, valuableAsset: _valuableAsset, isNFT: _isNFT, receiptID: _receiptID, oracles_Principles: _oracleIDS_Principles, ratio: _ratio, oracle_Collateral: _oracleID_Collateral, valuableAssetAmount: 0, availableAmount: _isNFT ? 1 : _startedBorrowAmount, startAmount: _startedBorrowAmount }); factoryContract = msg.sender; } /** * @dev Accepts the borrow offer -- only callable from Aggregator * @param amount Amount of the collateral to be accepted */ function acceptBorrowOffer( uint amount ) public onlyAggregator nonReentrant onlyAfterTimeOut { BorrowInfo memory m_borrowInformation = getBorrowInfo(); require( amount <= m_borrowInformation.availableAmount, "Amount exceeds available amount" ); require(amount > 0, "Amount must be greater than 0"); borrowInformation.availableAmount -= amount; // transfer collateral to aggregator if (m_borrowInformation.isNFT) { IERC721(m_borrowInformation.collateral).transferFrom( address(this), aggregatorContract, m_borrowInformation.receiptID ); } else { // has to be at least 5% of the available amount uint minAMOUNT = (m_borrowInformation.availableAmount) / 20; uint decimals = ERC20(m_borrowInformation.collateral).decimals(); uint thousandTokens = 1000 * 10 ** decimals; require( amount >= minAMOUNT || amount >= thousandTokens, "Amount too low" ); // get decimals SafeERC20.safeTransfer( IERC20(m_borrowInformation.collateral), aggregatorContract, amount ); } uint percentageOfAvailableCollateral = (borrowInformation .availableAmount * 10000) / m_borrowInformation.startAmount; // if available amount is less than 0.1% of the start amount, the order is no longer active and will count as completed. if (percentageOfAvailableCollateral <= 10) { isActive = false; // transfer remaining collateral back to owner if (borrowInformation.availableAmount != 0) { SafeERC20.safeTransfer( IERC20(m_borrowInformation.collateral), m_borrowInformation.owner, borrowInformation.availableAmount ); } borrowInformation.availableAmount = 0; IDBOFactory(factoryContract).emitDelete(address(this)); IDBOFactory(factoryContract).deleteBorrowOrder(address(this)); } else { IDBOFactory(factoryContract).emitUpdate(address(this)); } } /** * @dev Cancels the borrow offer -- only callable from owner */ function cancelOffer() public onlyOwner nonReentrant { BorrowInfo memory m_borrowInformation = getBorrowInfo(); uint availableAmount = m_borrowInformation.availableAmount; require(availableAmount > 0, "No available amount"); // set available amount to 0 // set isActive to false borrowInformation.availableAmount = 0; isActive = false; // transfer collateral back to owner if (m_borrowInformation.isNFT) { if (m_borrowInformation.availableAmount > 0) { IERC721(m_borrowInformation.collateral).transferFrom( address(this), msg.sender, m_borrowInformation.receiptID ); } } else { SafeERC20.safeTransfer( IERC20(m_borrowInformation.collateral), msg.sender, availableAmount ); } // emit canceled event on factory IDBOFactory(factoryContract).deleteBorrowOrder(address(this)); IDBOFactory(factoryContract).emitDelete(address(this)); } function getBorrowInfo() public view returns (BorrowInfo memory) { BorrowInfo memory m_borrowInformation = borrowInformation; // get dynamic data for NFTs if (m_borrowInformation.isNFT) { NFR.receiptInstance memory nftData = NFR( m_borrowInformation.collateral ).getDataByReceipt(m_borrowInformation.receiptID); m_borrowInformation.valuableAssetAmount = nftData.lockedAmount; } return m_borrowInformation; } function updateBorrowOrder( uint newMaxApr, uint newDuration, uint[] memory newLTVs, uint[] memory newRatios ) public onlyOwner { require( newLTVs.length == borrowInformation.acceptedPrinciples.length && newRatios.length == newLTVs.length, "Invalid LTVs" ); lastUpdate = block.timestamp; BorrowInfo memory m_borrowInformation = getBorrowInfo(); m_borrowInformation.maxApr = newMaxApr; m_borrowInformation.duration = newDuration; m_borrowInformation.LTVs = newLTVs; m_borrowInformation.ratio = newRatios; borrowInformation = m_borrowInformation; IDBOFactory(factoryContract).emitUpdate(address(this)); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.20; /** * @dev Interface of the ERC-20 standard as defined in the ERC. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the value of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the value of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves a `value` amount of tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 value) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets a `value` amount of tokens as the allowance of `spender` over the * caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 value) external returns (bool); /** * @dev Moves a `value` amount of tokens from `from` to `to` using the * allowance mechanism. `value` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 value) external returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.2.0) (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.20; import {IERC20} from "../IERC20.sol"; import {IERC1363} from "../../../interfaces/IERC1363.sol"; /** * @title SafeERC20 * @dev Wrappers around ERC-20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { /** * @dev An operation with an ERC-20 token failed. */ error SafeERC20FailedOperation(address token); /** * @dev Indicates a failed `decreaseAllowance` request. */ error SafeERC20FailedDecreaseAllowance(address spender, uint256 currentAllowance, uint256 requestedDecrease); /** * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeTransfer(IERC20 token, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeCall(token.transfer, (to, value))); } /** * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful. */ function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeCall(token.transferFrom, (from, to, value))); } /** * @dev Variant of {safeTransfer} that returns a bool instead of reverting if the operation is not successful. */ function trySafeTransfer(IERC20 token, address to, uint256 value) internal returns (bool) { return _callOptionalReturnBool(token, abi.encodeCall(token.transfer, (to, value))); } /** * @dev Variant of {safeTransferFrom} that returns a bool instead of reverting if the operation is not successful. */ function trySafeTransferFrom(IERC20 token, address from, address to, uint256 value) internal returns (bool) { return _callOptionalReturnBool(token, abi.encodeCall(token.transferFrom, (from, to, value))); } /** * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. * * IMPORTANT: If the token implements ERC-7674 (ERC-20 with temporary allowance), and if the "client" * smart contract uses ERC-7674 to set temporary allowances, then the "client" smart contract should avoid using * this function. Performing a {safeIncreaseAllowance} or {safeDecreaseAllowance} operation on a token contract * that has a non-zero temporary allowance (for that particular owner-spender) will result in unexpected behavior. */ function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 oldAllowance = token.allowance(address(this), spender); forceApprove(token, spender, oldAllowance + value); } /** * @dev Decrease the calling contract's allowance toward `spender` by `requestedDecrease`. If `token` returns no * value, non-reverting calls are assumed to be successful. * * IMPORTANT: If the token implements ERC-7674 (ERC-20 with temporary allowance), and if the "client" * smart contract uses ERC-7674 to set temporary allowances, then the "client" smart contract should avoid using * this function. Performing a {safeIncreaseAllowance} or {safeDecreaseAllowance} operation on a token contract * that has a non-zero temporary allowance (for that particular owner-spender) will result in unexpected behavior. */ function safeDecreaseAllowance(IERC20 token, address spender, uint256 requestedDecrease) internal { unchecked { uint256 currentAllowance = token.allowance(address(this), spender); if (currentAllowance < requestedDecrease) { revert SafeERC20FailedDecreaseAllowance(spender, currentAllowance, requestedDecrease); } forceApprove(token, spender, currentAllowance - requestedDecrease); } } /** * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval * to be set to zero before setting it to a non-zero value, such as USDT. * * NOTE: If the token implements ERC-7674, this function will not modify any temporary allowance. This function * only sets the "standard" allowance. Any temporary allowance will remain active, in addition to the value being * set here. */ function forceApprove(IERC20 token, address spender, uint256 value) internal { bytes memory approvalCall = abi.encodeCall(token.approve, (spender, value)); if (!_callOptionalReturnBool(token, approvalCall)) { _callOptionalReturn(token, abi.encodeCall(token.approve, (spender, 0))); _callOptionalReturn(token, approvalCall); } } /** * @dev Performs an {ERC1363} transferAndCall, with a fallback to the simple {ERC20} transfer if the target has no * code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when * targeting contracts. * * Reverts if the returned value is other than `true`. */ function transferAndCallRelaxed(IERC1363 token, address to, uint256 value, bytes memory data) internal { if (to.code.length == 0) { safeTransfer(token, to, value); } else if (!token.transferAndCall(to, value, data)) { revert SafeERC20FailedOperation(address(token)); } } /** * @dev Performs an {ERC1363} transferFromAndCall, with a fallback to the simple {ERC20} transferFrom if the target * has no code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when * targeting contracts. * * Reverts if the returned value is other than `true`. */ function transferFromAndCallRelaxed( IERC1363 token, address from, address to, uint256 value, bytes memory data ) internal { if (to.code.length == 0) { safeTransferFrom(token, from, to, value); } else if (!token.transferFromAndCall(from, to, value, data)) { revert SafeERC20FailedOperation(address(token)); } } /** * @dev Performs an {ERC1363} approveAndCall, with a fallback to the simple {ERC20} approve if the target has no * code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when * targeting contracts. * * NOTE: When the recipient address (`to`) has no code (i.e. is an EOA), this function behaves as {forceApprove}. * Opposedly, when the recipient address (`to`) has code, this function only attempts to call {ERC1363-approveAndCall} * once without retrying, and relies on the returned value to be true. * * Reverts if the returned value is other than `true`. */ function approveAndCallRelaxed(IERC1363 token, address to, uint256 value, bytes memory data) internal { if (to.code.length == 0) { forceApprove(token, to, value); } else if (!token.approveAndCall(to, value, data)) { revert SafeERC20FailedOperation(address(token)); } } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). * * This is a variant of {_callOptionalReturnBool} that reverts if call fails to meet the requirements. */ function _callOptionalReturn(IERC20 token, bytes memory data) private { uint256 returnSize; uint256 returnValue; assembly ("memory-safe") { let success := call(gas(), token, 0, add(data, 0x20), mload(data), 0, 0x20) // bubble errors if iszero(success) { let ptr := mload(0x40) returndatacopy(ptr, 0, returndatasize()) revert(ptr, returndatasize()) } returnSize := returndatasize() returnValue := mload(0) } if (returnSize == 0 ? address(token).code.length == 0 : returnValue != 1) { revert SafeERC20FailedOperation(address(token)); } } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). * * This is a variant of {_callOptionalReturn} that silently catches all reverts and returns a bool instead. */ function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) { bool success; uint256 returnSize; uint256 returnValue; assembly ("memory-safe") { success := call(gas(), token, 0, add(data, 0x20), mload(data), 0, 0x20) returnSize := returndatasize() returnValue := mload(0) } return success && (returnSize == 0 ? address(token).code.length > 0 : returnValue == 1); } }
pragma solidity ^0.8.0; import "@openzeppelin/contracts/proxy/Proxy.sol"; contract DebitaProxyContract is Proxy { constructor(address _logic) { bytes32 implementationPosition = bytes32( uint256(keccak256("eip1967.implementationSlot")) - 1 ); assembly { sstore(implementationPosition, _logic) } } function _implementation() internal view override returns (address) { bytes32 implementationPosition = bytes32( uint256(keccak256("eip1967.implementationSlot")) - 1 ); address implementationAddress; // sload and return implementationPosition assembly { implementationAddress := sload(implementationPosition) } return implementationAddress; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.2.0) (token/ERC20/ERC20.sol) pragma solidity ^0.8.20; import {IERC20} from "./IERC20.sol"; import {IERC20Metadata} from "./extensions/IERC20Metadata.sol"; import {Context} from "../../utils/Context.sol"; import {IERC20Errors} from "../../interfaces/draft-IERC6093.sol"; /** * @dev Implementation of the {IERC20} interface. * * This implementation is agnostic to the way tokens are created. This means * that a supply mechanism has to be added in a derived contract using {_mint}. * * TIP: For a detailed writeup see our guide * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How * to implement supply mechanisms]. * * The default value of {decimals} is 18. To change this, you should override * this function so it returns a different value. * * We have followed general OpenZeppelin Contracts guidelines: functions revert * instead returning `false` on failure. This behavior is nonetheless * conventional and does not conflict with the expectations of ERC-20 * applications. */ abstract contract ERC20 is Context, IERC20, IERC20Metadata, IERC20Errors { mapping(address account => uint256) private _balances; mapping(address account => mapping(address spender => uint256)) private _allowances; uint256 private _totalSupply; string private _name; string private _symbol; /** * @dev Sets the values for {name} and {symbol}. * * All two of these values are immutable: they can only be set once during * construction. */ constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; } /** * @dev Returns the name of the token. */ function name() public view virtual returns (string memory) { return _name; } /** * @dev Returns the symbol of the token, usually a shorter version of the * name. */ function symbol() public view virtual returns (string memory) { return _symbol; } /** * @dev Returns the number of decimals used to get its user representation. * For example, if `decimals` equals `2`, a balance of `505` tokens should * be displayed to a user as `5.05` (`505 / 10 ** 2`). * * Tokens usually opt for a value of 18, imitating the relationship between * Ether and Wei. This is the default value returned by this function, unless * it's overridden. * * NOTE: This information is only used for _display_ purposes: it in * no way affects any of the arithmetic of the contract, including * {IERC20-balanceOf} and {IERC20-transfer}. */ function decimals() public view virtual returns (uint8) { return 18; } /** * @dev See {IERC20-totalSupply}. */ function totalSupply() public view virtual returns (uint256) { return _totalSupply; } /** * @dev See {IERC20-balanceOf}. */ function balanceOf(address account) public view virtual returns (uint256) { return _balances[account]; } /** * @dev See {IERC20-transfer}. * * Requirements: * * - `to` cannot be the zero address. * - the caller must have a balance of at least `value`. */ function transfer(address to, uint256 value) public virtual returns (bool) { address owner = _msgSender(); _transfer(owner, to, value); return true; } /** * @dev See {IERC20-allowance}. */ function allowance(address owner, address spender) public view virtual returns (uint256) { return _allowances[owner][spender]; } /** * @dev See {IERC20-approve}. * * NOTE: If `value` is the maximum `uint256`, the allowance is not updated on * `transferFrom`. This is semantically equivalent to an infinite approval. * * Requirements: * * - `spender` cannot be the zero address. */ function approve(address spender, uint256 value) public virtual returns (bool) { address owner = _msgSender(); _approve(owner, spender, value); return true; } /** * @dev See {IERC20-transferFrom}. * * Skips emitting an {Approval} event indicating an allowance update. This is not * required by the ERC. See {xref-ERC20-_approve-address-address-uint256-bool-}[_approve]. * * NOTE: Does not update the allowance if the current allowance * is the maximum `uint256`. * * Requirements: * * - `from` and `to` cannot be the zero address. * - `from` must have a balance of at least `value`. * - the caller must have allowance for ``from``'s tokens of at least * `value`. */ function transferFrom(address from, address to, uint256 value) public virtual returns (bool) { address spender = _msgSender(); _spendAllowance(from, spender, value); _transfer(from, to, value); return true; } /** * @dev Moves a `value` amount of tokens from `from` to `to`. * * This internal function is equivalent to {transfer}, and can be used to * e.g. implement automatic token fees, slashing mechanisms, etc. * * Emits a {Transfer} event. * * NOTE: This function is not virtual, {_update} should be overridden instead. */ function _transfer(address from, address to, uint256 value) internal { if (from == address(0)) { revert ERC20InvalidSender(address(0)); } if (to == address(0)) { revert ERC20InvalidReceiver(address(0)); } _update(from, to, value); } /** * @dev Transfers a `value` amount of tokens from `from` to `to`, or alternatively mints (or burns) if `from` * (or `to`) is the zero address. All customizations to transfers, mints, and burns should be done by overriding * this function. * * Emits a {Transfer} event. */ function _update(address from, address to, uint256 value) internal virtual { if (from == address(0)) { // Overflow check required: The rest of the code assumes that totalSupply never overflows _totalSupply += value; } else { uint256 fromBalance = _balances[from]; if (fromBalance < value) { revert ERC20InsufficientBalance(from, fromBalance, value); } unchecked { // Overflow not possible: value <= fromBalance <= totalSupply. _balances[from] = fromBalance - value; } } if (to == address(0)) { unchecked { // Overflow not possible: value <= totalSupply or value <= fromBalance <= totalSupply. _totalSupply -= value; } } else { unchecked { // Overflow not possible: balance + value is at most totalSupply, which we know fits into a uint256. _balances[to] += value; } } emit Transfer(from, to, value); } /** * @dev Creates a `value` amount of tokens and assigns them to `account`, by transferring it from address(0). * Relies on the `_update` mechanism * * Emits a {Transfer} event with `from` set to the zero address. * * NOTE: This function is not virtual, {_update} should be overridden instead. */ function _mint(address account, uint256 value) internal { if (account == address(0)) { revert ERC20InvalidReceiver(address(0)); } _update(address(0), account, value); } /** * @dev Destroys a `value` amount of tokens from `account`, lowering the total supply. * Relies on the `_update` mechanism. * * Emits a {Transfer} event with `to` set to the zero address. * * NOTE: This function is not virtual, {_update} should be overridden instead */ function _burn(address account, uint256 value) internal { if (account == address(0)) { revert ERC20InvalidSender(address(0)); } _update(account, address(0), value); } /** * @dev Sets `value` as the allowance of `spender` over the `owner` s tokens. * * This internal function is equivalent to `approve`, and can be used to * e.g. set automatic allowances for certain subsystems, etc. * * Emits an {Approval} event. * * Requirements: * * - `owner` cannot be the zero address. * - `spender` cannot be the zero address. * * Overrides to this logic should be done to the variant with an additional `bool emitEvent` argument. */ function _approve(address owner, address spender, uint256 value) internal { _approve(owner, spender, value, true); } /** * @dev Variant of {_approve} with an optional flag to enable or disable the {Approval} event. * * By default (when calling {_approve}) the flag is set to true. On the other hand, approval changes made by * `_spendAllowance` during the `transferFrom` operation set the flag to false. This saves gas by not emitting any * `Approval` event during `transferFrom` operations. * * Anyone who wishes to continue emitting `Approval` events on the`transferFrom` operation can force the flag to * true using the following override: * * ```solidity * function _approve(address owner, address spender, uint256 value, bool) internal virtual override { * super._approve(owner, spender, value, true); * } * ``` * * Requirements are the same as {_approve}. */ function _approve(address owner, address spender, uint256 value, bool emitEvent) internal virtual { if (owner == address(0)) { revert ERC20InvalidApprover(address(0)); } if (spender == address(0)) { revert ERC20InvalidSpender(address(0)); } _allowances[owner][spender] = value; if (emitEvent) { emit Approval(owner, spender, value); } } /** * @dev Updates `owner` s allowance for `spender` based on spent `value`. * * Does not update the allowance value in case of infinite allowance. * Revert if not enough allowance is available. * * Does not emit an {Approval} event. */ function _spendAllowance(address owner, address spender, uint256 value) internal virtual { uint256 currentAllowance = allowance(owner, spender); if (currentAllowance < type(uint256).max) { if (currentAllowance < value) { revert ERC20InsufficientAllowance(spender, currentAllowance, value); } unchecked { _approve(owner, spender, currentAllowance - value, false); } } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (token/ERC721/IERC721.sol) pragma solidity ^0.8.20; import {IERC165} from "../../utils/introspection/IERC165.sol"; /** * @dev Required interface of an ERC-721 compliant contract. */ interface IERC721 is IERC165 { /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /** * @dev Returns the number of tokens in ``owner``'s account. */ function balanceOf(address owner) external view returns (uint256 balance); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); /** * @dev Safely transfers `tokenId` token from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon * a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external; /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC-721 protocol to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or * {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon * a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom(address from, address to, uint256 tokenId) external; /** * @dev Transfers `tokenId` token from `from` to `to`. * * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC-721 * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must * understand this adds an external call which potentially creates a reentrancy vulnerability. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 tokenId) external; /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external; /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the address zero. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool approved) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll} */ function isApprovedForAll(address owner, address operator) external view returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/utils/ERC721Holder.sol) pragma solidity ^0.8.20; import {IERC721Receiver} from "../IERC721Receiver.sol"; /** * @dev Implementation of the {IERC721Receiver} interface. * * Accepts all token transfers. * Make sure the contract is able to use its token with {IERC721-safeTransferFrom}, {IERC721-approve} or * {IERC721-setApprovalForAll}. */ abstract contract ERC721Holder is IERC721Receiver { /** * @dev See {IERC721Receiver-onERC721Received}. * * Always returns `IERC721Receiver.onERC721Received.selector`. */ function onERC721Received(address, address, uint256, bytes memory) public virtual returns (bytes4) { return this.onERC721Received.selector; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (utils/ReentrancyGuard.sol) pragma solidity ^0.8.20; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If EIP-1153 (transient storage) is available on the chain you're deploying at, * consider using {ReentrancyGuardTransient} instead. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuard { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant NOT_ENTERED = 1; uint256 private constant ENTERED = 2; uint256 private _status; /** * @dev Unauthorized reentrant call. */ error ReentrancyGuardReentrantCall(); constructor() { _status = NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and making it call a * `private` function that does the actual work. */ modifier nonReentrant() { _nonReentrantBefore(); _; _nonReentrantAfter(); } function _nonReentrantBefore() private { // On the first call to nonReentrant, _status will be NOT_ENTERED if (_status == ENTERED) { revert ReentrancyGuardReentrantCall(); } // Any calls to nonReentrant after this point will fail _status = ENTERED; } function _nonReentrantAfter() private { // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = NOT_ENTERED; } /** * @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a * `nonReentrant` function in the call stack. */ function _reentrancyGuardEntered() internal view returns (bool) { return _status == ENTERED; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (proxy/utils/Initializable.sol) pragma solidity ^0.8.20; /** * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. * * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be * reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in * case an upgrade adds a module that needs to be initialized. * * For example: * * [.hljs-theme-light.nopadding] * ```solidity * contract MyToken is ERC20Upgradeable { * function initialize() initializer public { * __ERC20_init("MyToken", "MTK"); * } * } * * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable { * function initializeV2() reinitializer(2) public { * __ERC20Permit_init("MyToken"); * } * } * ``` * * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. * * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. * * [CAUTION] * ==== * Avoid leaving a contract uninitialized. * * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed: * * [.hljs-theme-light.nopadding] * ``` * /// @custom:oz-upgrades-unsafe-allow constructor * constructor() { * _disableInitializers(); * } * ``` * ==== */ abstract contract Initializable { /** * @dev Storage of the initializable contract. * * It's implemented on a custom ERC-7201 namespace to reduce the risk of storage collisions * when using with upgradeable contracts. * * @custom:storage-location erc7201:openzeppelin.storage.Initializable */ struct InitializableStorage { /** * @dev Indicates that the contract has been initialized. */ uint64 _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool _initializing; } // keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.Initializable")) - 1)) & ~bytes32(uint256(0xff)) bytes32 private constant INITIALIZABLE_STORAGE = 0xf0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00; /** * @dev The contract is already initialized. */ error InvalidInitialization(); /** * @dev The contract is not initializing. */ error NotInitializing(); /** * @dev Triggered when the contract has been initialized or reinitialized. */ event Initialized(uint64 version); /** * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope, * `onlyInitializing` functions can be used to initialize parent contracts. * * Similar to `reinitializer(1)`, except that in the context of a constructor an `initializer` may be invoked any * number of times. This behavior in the constructor can be useful during testing and is not expected to be used in * production. * * Emits an {Initialized} event. */ modifier initializer() { // solhint-disable-next-line var-name-mixedcase InitializableStorage storage $ = _getInitializableStorage(); // Cache values to avoid duplicated sloads bool isTopLevelCall = !$._initializing; uint64 initialized = $._initialized; // Allowed calls: // - initialSetup: the contract is not in the initializing state and no previous version was // initialized // - construction: the contract is initialized at version 1 (no reininitialization) and the // current contract is just being deployed bool initialSetup = initialized == 0 && isTopLevelCall; bool construction = initialized == 1 && address(this).code.length == 0; if (!initialSetup && !construction) { revert InvalidInitialization(); } $._initialized = 1; if (isTopLevelCall) { $._initializing = true; } _; if (isTopLevelCall) { $._initializing = false; emit Initialized(1); } } /** * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be * used to initialize parent contracts. * * A reinitializer may be used after the original initialization step. This is essential to configure modules that * are added through upgrades and that require initialization. * * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer` * cannot be nested. If one is invoked in the context of another, execution will revert. * * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in * a contract, executing them in the right order is up to the developer or operator. * * WARNING: Setting the version to 2**64 - 1 will prevent any future reinitialization. * * Emits an {Initialized} event. */ modifier reinitializer(uint64 version) { // solhint-disable-next-line var-name-mixedcase InitializableStorage storage $ = _getInitializableStorage(); if ($._initializing || $._initialized >= version) { revert InvalidInitialization(); } $._initialized = version; $._initializing = true; _; $._initializing = false; emit Initialized(version); } /** * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the * {initializer} and {reinitializer} modifiers, directly or indirectly. */ modifier onlyInitializing() { _checkInitializing(); _; } /** * @dev Reverts if the contract is not in an initializing state. See {onlyInitializing}. */ function _checkInitializing() internal view virtual { if (!_isInitializing()) { revert NotInitializing(); } } /** * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call. * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized * to any version. It is recommended to use this to lock implementation contracts that are designed to be called * through proxies. * * Emits an {Initialized} event the first time it is successfully executed. */ function _disableInitializers() internal virtual { // solhint-disable-next-line var-name-mixedcase InitializableStorage storage $ = _getInitializableStorage(); if ($._initializing) { revert InvalidInitialization(); } if ($._initialized != type(uint64).max) { $._initialized = type(uint64).max; emit Initialized(type(uint64).max); } } /** * @dev Returns the highest version that has been initialized. See {reinitializer}. */ function _getInitializedVersion() internal view returns (uint64) { return _getInitializableStorage()._initialized; } /** * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}. */ function _isInitializing() internal view returns (bool) { return _getInitializableStorage()._initializing; } /** * @dev Pointer to storage slot. Allows integrators to override it with a custom storage location. * * NOTE: Consider following the ERC-7201 formula to derive storage locations. */ function _initializableStorageSlot() internal pure virtual returns (bytes32) { return INITIALIZABLE_STORAGE; } /** * @dev Returns a pointer to the storage namespace. */ // solhint-disable-next-line var-name-mixedcase function _getInitializableStorage() private pure returns (InitializableStorage storage $) { bytes32 slot = _initializableStorageSlot(); assembly { $.slot := slot } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (interfaces/IERC1363.sol) pragma solidity ^0.8.20; import {IERC20} from "./IERC20.sol"; import {IERC165} from "./IERC165.sol"; /** * @title IERC1363 * @dev Interface of the ERC-1363 standard as defined in the https://eips.ethereum.org/EIPS/eip-1363[ERC-1363]. * * Defines an extension interface for ERC-20 tokens that supports executing code on a recipient contract * after `transfer` or `transferFrom`, or code on a spender contract after `approve`, in a single transaction. */ interface IERC1363 is IERC20, IERC165 { /* * Note: the ERC-165 identifier for this interface is 0xb0202a11. * 0xb0202a11 === * bytes4(keccak256('transferAndCall(address,uint256)')) ^ * bytes4(keccak256('transferAndCall(address,uint256,bytes)')) ^ * bytes4(keccak256('transferFromAndCall(address,address,uint256)')) ^ * bytes4(keccak256('transferFromAndCall(address,address,uint256,bytes)')) ^ * bytes4(keccak256('approveAndCall(address,uint256)')) ^ * bytes4(keccak256('approveAndCall(address,uint256,bytes)')) */ /** * @dev Moves a `value` amount of tokens from the caller's account to `to` * and then calls {IERC1363Receiver-onTransferReceived} on `to`. * @param to The address which you want to transfer to. * @param value The amount of tokens to be transferred. * @return A boolean value indicating whether the operation succeeded unless throwing. */ function transferAndCall(address to, uint256 value) external returns (bool); /** * @dev Moves a `value` amount of tokens from the caller's account to `to` * and then calls {IERC1363Receiver-onTransferReceived} on `to`. * @param to The address which you want to transfer to. * @param value The amount of tokens to be transferred. * @param data Additional data with no specified format, sent in call to `to`. * @return A boolean value indicating whether the operation succeeded unless throwing. */ function transferAndCall(address to, uint256 value, bytes calldata data) external returns (bool); /** * @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism * and then calls {IERC1363Receiver-onTransferReceived} on `to`. * @param from The address which you want to send tokens from. * @param to The address which you want to transfer to. * @param value The amount of tokens to be transferred. * @return A boolean value indicating whether the operation succeeded unless throwing. */ function transferFromAndCall(address from, address to, uint256 value) external returns (bool); /** * @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism * and then calls {IERC1363Receiver-onTransferReceived} on `to`. * @param from The address which you want to send tokens from. * @param to The address which you want to transfer to. * @param value The amount of tokens to be transferred. * @param data Additional data with no specified format, sent in call to `to`. * @return A boolean value indicating whether the operation succeeded unless throwing. */ function transferFromAndCall(address from, address to, uint256 value, bytes calldata data) external returns (bool); /** * @dev Sets a `value` amount of tokens as the allowance of `spender` over the * caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`. * @param spender The address which will spend the funds. * @param value The amount of tokens to be spent. * @return A boolean value indicating whether the operation succeeded unless throwing. */ function approveAndCall(address spender, uint256 value) external returns (bool); /** * @dev Sets a `value` amount of tokens as the allowance of `spender` over the * caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`. * @param spender The address which will spend the funds. * @param value The amount of tokens to be spent. * @param data Additional data with no specified format, sent in call to `spender`. * @return A boolean value indicating whether the operation succeeded unless throwing. */ function approveAndCall(address spender, uint256 value, bytes calldata data) external returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (proxy/Proxy.sol) pragma solidity ^0.8.20; /** * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to * be specified by overriding the virtual {_implementation} function. * * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a * different contract through the {_delegate} function. * * The success and return data of the delegated call will be returned back to the caller of the proxy. */ abstract contract Proxy { /** * @dev Delegates the current call to `implementation`. * * This function does not return to its internal call site, it will return directly to the external caller. */ function _delegate(address implementation) internal virtual { assembly { // Copy msg.data. We take full control of memory in this inline assembly // block because it will not return to Solidity code. We overwrite the // Solidity scratch pad at memory position 0. calldatacopy(0, 0, calldatasize()) // Call the implementation. // out and outsize are 0 because we don't know the size yet. let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0) // Copy the returned data. returndatacopy(0, 0, returndatasize()) switch result // delegatecall returns 0 on error. case 0 { revert(0, returndatasize()) } default { return(0, returndatasize()) } } } /** * @dev This is a virtual function that should be overridden so it returns the address to which the fallback * function and {_fallback} should delegate. */ function _implementation() internal view virtual returns (address); /** * @dev Delegates the current call to the address returned by `_implementation()`. * * This function does not return to its internal call site, it will return directly to the external caller. */ function _fallback() internal virtual { _delegate(_implementation()); } /** * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other * function in the contract matches the call data. */ fallback() external payable virtual { _fallback(); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/extensions/IERC20Metadata.sol) pragma solidity ^0.8.20; import {IERC20} from "../IERC20.sol"; /** * @dev Interface for the optional metadata functions from the ERC-20 standard. */ interface IERC20Metadata is IERC20 { /** * @dev Returns the name of the token. */ function name() external view returns (string memory); /** * @dev Returns the symbol of the token. */ function symbol() external view returns (string memory); /** * @dev Returns the decimals places of the token. */ function decimals() external view returns (uint8); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol) pragma solidity ^0.8.20; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } function _contextSuffixLength() internal view virtual returns (uint256) { return 0; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (interfaces/draft-IERC6093.sol) pragma solidity ^0.8.20; /** * @dev Standard ERC-20 Errors * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-20 tokens. */ interface IERC20Errors { /** * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. * @param balance Current balance for the interacting account. * @param needed Minimum amount required to perform a transfer. */ error ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed); /** * @dev Indicates a failure with the token `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. */ error ERC20InvalidSender(address sender); /** * @dev Indicates a failure with the token `receiver`. Used in transfers. * @param receiver Address to which tokens are being transferred. */ error ERC20InvalidReceiver(address receiver); /** * @dev Indicates a failure with the `spender`’s `allowance`. Used in transfers. * @param spender Address that may be allowed to operate on tokens without being their owner. * @param allowance Amount of tokens a `spender` is allowed to operate with. * @param needed Minimum amount required to perform a transfer. */ error ERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed); /** * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals. * @param approver Address initiating an approval operation. */ error ERC20InvalidApprover(address approver); /** * @dev Indicates a failure with the `spender` to be approved. Used in approvals. * @param spender Address that may be allowed to operate on tokens without being their owner. */ error ERC20InvalidSpender(address spender); } /** * @dev Standard ERC-721 Errors * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-721 tokens. */ interface IERC721Errors { /** * @dev Indicates that an address can't be an owner. For example, `address(0)` is a forbidden owner in ERC-20. * Used in balance queries. * @param owner Address of the current owner of a token. */ error ERC721InvalidOwner(address owner); /** * @dev Indicates a `tokenId` whose `owner` is the zero address. * @param tokenId Identifier number of a token. */ error ERC721NonexistentToken(uint256 tokenId); /** * @dev Indicates an error related to the ownership over a particular token. Used in transfers. * @param sender Address whose tokens are being transferred. * @param tokenId Identifier number of a token. * @param owner Address of the current owner of a token. */ error ERC721IncorrectOwner(address sender, uint256 tokenId, address owner); /** * @dev Indicates a failure with the token `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. */ error ERC721InvalidSender(address sender); /** * @dev Indicates a failure with the token `receiver`. Used in transfers. * @param receiver Address to which tokens are being transferred. */ error ERC721InvalidReceiver(address receiver); /** * @dev Indicates a failure with the `operator`’s approval. Used in transfers. * @param operator Address that may be allowed to operate on tokens without being their owner. * @param tokenId Identifier number of a token. */ error ERC721InsufficientApproval(address operator, uint256 tokenId); /** * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals. * @param approver Address initiating an approval operation. */ error ERC721InvalidApprover(address approver); /** * @dev Indicates a failure with the `operator` to be approved. Used in approvals. * @param operator Address that may be allowed to operate on tokens without being their owner. */ error ERC721InvalidOperator(address operator); } /** * @dev Standard ERC-1155 Errors * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-1155 tokens. */ interface IERC1155Errors { /** * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. * @param balance Current balance for the interacting account. * @param needed Minimum amount required to perform a transfer. * @param tokenId Identifier number of a token. */ error ERC1155InsufficientBalance(address sender, uint256 balance, uint256 needed, uint256 tokenId); /** * @dev Indicates a failure with the token `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. */ error ERC1155InvalidSender(address sender); /** * @dev Indicates a failure with the token `receiver`. Used in transfers. * @param receiver Address to which tokens are being transferred. */ error ERC1155InvalidReceiver(address receiver); /** * @dev Indicates a failure with the `operator`’s approval. Used in transfers. * @param operator Address that may be allowed to operate on tokens without being their owner. * @param owner Address of the current owner of a token. */ error ERC1155MissingApprovalForAll(address operator, address owner); /** * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals. * @param approver Address initiating an approval operation. */ error ERC1155InvalidApprover(address approver); /** * @dev Indicates a failure with the `operator` to be approved. Used in approvals. * @param operator Address that may be allowed to operate on tokens without being their owner. */ error ERC1155InvalidOperator(address operator); /** * @dev Indicates an array length mismatch between ids and values in a safeBatchTransferFrom operation. * Used in batch transfers. * @param idsLength Length of the array of token identifiers * @param valuesLength Length of the array of token amounts */ error ERC1155InvalidArrayLength(uint256 idsLength, uint256 valuesLength); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (utils/introspection/IERC165.sol) pragma solidity ^0.8.20; /** * @dev Interface of the ERC-165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[ERC]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[ERC section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (token/ERC721/IERC721Receiver.sol) pragma solidity ^0.8.20; /** * @title ERC-721 token receiver interface * @dev Interface for any contract that wants to support safeTransfers * from ERC-721 asset contracts. */ interface IERC721Receiver { /** * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom} * by `operator` from `from`, this function is called. * * It must return its Solidity selector to confirm the token transfer. * If any other value is returned or the interface is not implemented by the recipient, the transfer will be * reverted. * * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`. */ function onERC721Received( address operator, address from, uint256 tokenId, bytes calldata data ) external returns (bytes4); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC20.sol) pragma solidity ^0.8.20; import {IERC20} from "../token/ERC20/IERC20.sol";
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC165.sol) pragma solidity ^0.8.20; import {IERC165} from "../utils/introspection/IERC165.sol";
{ "remappings": [ "@pythnetwork/pyth-sdk-solidity/=node_modules/@pythnetwork/pyth-sdk-solidity/", "@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/", "@contracts/=contracts/", "@aerodrome/=lib/contracts/contracts/", "forge-std/=lib/forge-std/src/", "@redstone-finance/evm-connector/dist/contracts/=lib/redstone-oracles-monorepo/packages/evm-connector/contracts/", "@chainlink/=lib/foundry-chainlink-toolkit/", "@opengsn/=lib/contracts/lib/gsn/packages/", "@uniswap/v3-core/=lib/contracts/lib/v3-core/", "chainlink-brownie-contracts/=lib/foundry-chainlink-toolkit/lib/chainlink-brownie-contracts/contracts/src/v0.6/vendor/@arbitrum/nitro-contracts/src/", "contracts/=lib/contracts/contracts/", "ds-test/=lib/contracts/lib/ds-test/src/", "erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/", "foundry-chainlink-toolkit/=lib/foundry-chainlink-toolkit/", "gsn/=lib/contracts/lib/", "halmos-cheatcodes/=lib/openzeppelin-contracts/lib/halmos-cheatcodes/src/", "openzeppelin-contracts/=lib/openzeppelin-contracts/", "redstone-oracles-monorepo/=lib/redstone-oracles-monorepo/", "utils/=lib/contracts/test/utils/", "v3-core/=lib/contracts/lib/v3-core/" ], "optimizer": { "enabled": true, "runs": 200 }, "metadata": { "useLiteralContent": false, "bytecodeHash": "ipfs", "appendCBOR": true }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "evmVersion": "shanghai", "viaIR": true, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"_implementationContract","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"SafeERC20FailedOperation","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"borrowOrder","type":"address"},{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"uint256","name":"maxApr","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"duration","type":"uint256"},{"indexed":false,"internalType":"uint256[]","name":"LTVs","type":"uint256[]"},{"indexed":false,"internalType":"uint256[]","name":"ratios","type":"uint256[]"},{"indexed":false,"internalType":"uint256","name":"availableAmount","type":"uint256"},{"indexed":false,"internalType":"bool","name":"isActive","type":"bool"}],"name":"BorrowOrderCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"borrowOrder","type":"address"},{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"uint256","name":"maxApr","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"duration","type":"uint256"},{"indexed":false,"internalType":"uint256[]","name":"LTVs","type":"uint256[]"},{"indexed":false,"internalType":"uint256[]","name":"ratios","type":"uint256[]"},{"indexed":false,"internalType":"uint256","name":"availableAmount","type":"uint256"},{"indexed":false,"internalType":"bool","name":"isActive","type":"bool"}],"name":"BorrowOrderDeleted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"borrowOrder","type":"address"},{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"uint256","name":"maxApr","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"duration","type":"uint256"},{"indexed":false,"internalType":"uint256[]","name":"LTVs","type":"uint256[]"},{"indexed":false,"internalType":"uint256[]","name":"ratios","type":"uint256[]"},{"indexed":false,"internalType":"uint256","name":"availableAmount","type":"uint256"},{"indexed":false,"internalType":"bool","name":"isActive","type":"bool"}],"name":"BorrowOrderUpdated","type":"event"},{"inputs":[],"name":"activeOrdersCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"allActiveBorrowOrders","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"borrowOrderIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool[]","name":"_oraclesActivated","type":"bool[]"},{"internalType":"uint256[]","name":"_LTVs","type":"uint256[]"},{"internalType":"uint256","name":"_maxInterestRate","type":"uint256"},{"internalType":"uint256","name":"_duration","type":"uint256"},{"internalType":"address[]","name":"_acceptedPrinciples","type":"address[]"},{"internalType":"address","name":"_collateral","type":"address"},{"internalType":"bool","name":"_isNFT","type":"bool"},{"internalType":"uint256","name":"_receiptID","type":"uint256"},{"internalType":"address[]","name":"_oracleIDS_Principles","type":"address[]"},{"internalType":"uint256[]","name":"_ratio","type":"uint256[]"},{"internalType":"address","name":"_oracleID_Collateral","type":"address"},{"internalType":"uint256","name":"_collateralAmount","type":"uint256"}],"name":"createBorrowOrder","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_borrowOrder","type":"address"}],"name":"deleteBorrowOrder","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_borrowOrder","type":"address"}],"name":"emitDelete","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_borrowOrder","type":"address"}],"name":"emitUpdate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"offset","type":"uint256"},{"internalType":"uint256","name":"limit","type":"uint256"}],"name":"getActiveBorrowOrders","outputs":[{"components":[{"internalType":"address","name":"borrowOrderAddress","type":"address"},{"internalType":"bool[]","name":"oraclesPerPairActivated","type":"bool[]"},{"internalType":"uint256[]","name":"LTVs","type":"uint256[]"},{"internalType":"uint256","name":"maxApr","type":"uint256"},{"internalType":"uint256","name":"duration","type":"uint256"},{"internalType":"address","name":"owner","type":"address"},{"internalType":"address[]","name":"acceptedPrinciples","type":"address[]"},{"internalType":"address","name":"collateral","type":"address"},{"internalType":"address","name":"valuableAsset","type":"address"},{"internalType":"bool","name":"isNFT","type":"bool"},{"internalType":"uint256","name":"receiptID","type":"uint256"},{"internalType":"address[]","name":"oracles_Principles","type":"address[]"},{"internalType":"uint256[]","name":"ratio","type":"uint256[]"},{"internalType":"address","name":"oracle_Collateral","type":"address"},{"internalType":"uint256","name":"valuableAssetAmount","type":"uint256"},{"internalType":"uint256","name":"availableAmount","type":"uint256"},{"internalType":"uint256","name":"startAmount","type":"uint256"}],"internalType":"struct DBOImplementation.BorrowInfo[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isBorrowOrderLegit","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_aggregatorContract","type":"address"}],"name":"setAggregatorContract","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60803461007a57601f61180a38819003918201601f19168301916001600160401b0383118484101761007e5780849260209460405283398101031261007a57516001600160a01b0381169081900361007a5760018060a01b031933816006541617600655600554161760055560405161177790816100938239f35b5f80fd5b634e487b7160e01b5f52604160045260245ffdfe6080806040526004361015610012575f80fd5b5f9060e0908235821c9081633ff1b8d61461110e575080636ba840b5146110db5780638da5cb5b146110b25780639967cf6014610fdd5780639ac6a87814610ed5578063a7401ce414610e97578063b148414c14610d61578063cadbe0e014610bcd578063d499a19314610b94578063e07cd799146103da5763e136703014610099575f80fd5b346103d65760403660031901126103d65760043590602435916003548084116103ce575b50808303918383116103ba576100d2836111ab565b926100e06040519485611189565b8084526100ef601f19916111ab565b01855b818110610334575050845b84610108848361134c565b10156101a6578061011b6004928561134c565b87526002602052604080882054905163e1a7f11560e01b815292889184919082906001600160a01b03165afa801561019b57610174928891610179575b506101638287611608565b5261016e8186611608565b506112fe565b6100fd565b61019591503d808a833e61018d8183611189565b81019061143e565b5f610158565b6040513d89823e3d90fd5b858285604051916020808401918185528351809352604085018260408560051b88010195019680925b8584106101dc5787870388f35b909192939495603f1988820301845285895191610220928382019360018060a01b0394858351168452848301519185850152815180915284610240850192019088905b8082106103185750505091816102d86102c461028161024e8897604060019b980151878203604089015261128f565b606080860151908701526080808601519087015260a08781870151169087015260c08086015190878303908801526112c2565b858a850151168a860152610100868186015116908601526101208085015115159086015261014080850151908601526101608085015190868303908701526112c2565b61018080840151908583039086015261128f565b926101a0908183015116908301526101c080820151908301526101e08082015190830152610200809101519101529a0194019401929795949391906101cf565b8251151584528c9693840193909201916001919091019061021f565b6020906040516103438161116c565b8881526060839080828401528060408401528a818401528a60808401528a60a08401528060c08401528a878401528a6101008401528a6101208401528a61014084015280610160840152610180830152896101a0830152896101c0830152896101e0830152896102008301528288010152016100f2565b634e487b7160e01b5f52601160045260245ffd5b92505f6100bd565b5080fd5b823461087e5761018036600319011261087e5760043567ffffffffffffffff81116103d657366023820112156103d657806004013591610419836111ab565b916104276040519384611189565b83835260208301906024829560051b82010190368211610b7357602401915b818310610b7b5750505060243567ffffffffffffffff81116103d6576104709036906004016111c3565b9060843567ffffffffffffffff81116103d657610491903690600401611221565b60a43591906001600160a01b03831683036103d65760c435151560c435036103d6576101043567ffffffffffffffff8111610b77576104d4903690600401611221565b956101243567ffffffffffffffff8111610b73576104f69036906004016111c3565b9661014435916001600160a01b0383168303610b6f5760c435610ad8575b8651845103610aa4578151845103610a6e578751845103610a37578851845103610a025761016435156109c457600554604051906001600160a01b031667ffffffffffffffff6101118301908111908311176109b0576101116116318339610111820152602081610111810103019086f080156109a5576004546001600160a01b0391821699911694893b156109a1579491939092869360206105de60405198899663d52604ff60e01b885260048801523360248801526101c060448801526101c48701906112c2565b6001600160a01b038b166064870152858103600319016084870152915180835291019590855b818110610983575050506106646106779161063785969760c435151560a48801526003198782030160c48801528c61128f565b9060443560e487015260643561010487015260e435610124870152600319868303016101448701526112c2565b838103600319016101648501528b61128f565b6001600160a01b03909116610184830152610164356101a4830152038183895af1801561097857610969575b50838152602081905260408120805460ff191660011790559060c435156108b4576001600160a01b0381163b156103d6576040516323b872dd60e01b81523360048201526001600160a01b038516602482015260e4356044820152828180606481010381836001600160a01b0387165af180156108a957908391610895575b505060206024915b6003548685526001835280604086205584526002825260408420866001600160601b0360a01b8254161790556107616003546112fe565b6003556040516370a0823160e01b81526004810187905292839182906001600160a01b03165afa918215610889578092610851575b5050610164351161081a57817f400ed65e0cf279c2660526497d8f603f1d86d78dfb01b019a0d337a105166e5d6107fb6020956107ed6040519560443587526064358988015260c0604088015260c087019061128f565b90858203606087015261128f565b92610164356080820152600160a08201528033940390a3604051908152f35b60405162461bcd60e51b815260206004820152600f60248201526e496e76616c69642062616c616e636560881b6044820152606490fd5b9091506020823d602011610881575b8161086d60209383611189565b8101031261087e5750518480610796565b80fd5b3d9150610860565b604051903d90823e3d90fd5b61089e90611144565b6103d6578186610722565b6040513d85823e3d90fd5b6040516323b872dd60e01b60208083019182523360248401526001600160a01b0387166044840152610164356064808501919091528352918491906108fa608482611189565b5190826001600160a01b0386165af11561095c5781513d61095357506001600160a01b0381163b155b61093157602060249161072a565b604051635274afe760e01b81526001600160a01b039091166004820152602490fd5b60011415610923565b50604051903d90823e3d90fd5b61097290611144565b856106a3565b6040513d84823e3d90fd5b8251151588526020978801978a975089965090920191600101610604565b8680fd5b6040513d87823e3d90fd5b634e487b7160e01b87526041600452602487fd5b60405162461bcd60e51b8152602060048201526016602482015275125b9d985b1a59081cdd185c9d195908185b5bdd5b9d60521b6044820152606490fd5b60405162461bcd60e51b815260206004820152600d60248201526c496e76616c696420726174696f60981b6044820152606490fd5b60405162461bcd60e51b815260206004820152600f60248201526e496e76616c6964206f7261636c657360881b6044820152606490fd5b60405162461bcd60e51b815260206004820152600e60248201526d092dcecc2d8d2c840d8cadccee8d60931b6044820152606490fd5b60405162461bcd60e51b815260206004820152600c60248201526b496e76616c6964204c54567360a01b6044820152606490fd5b60e43515610b315760016101643503156105145760405162461bcd60e51b815260206004820152601f60248201527f5374617274656420426f72726f7720416d6f756e74206d7573742062652031006044820152606490fd5b60405162461bcd60e51b81526020600482015260166024820152750526563656970742049442063616e6e6f7420626520360541b6044820152606490fd5b8480fd5b8380fd5b8280fd5b82358015158103610b6f57815260209283019201610446565b823461087e57602036600319011261087e576020906040906001600160a01b03610bbc61112a565b168152600183522054604051908152f35b823461087e576020806003193601126103d657610be861112a565b338352828252610bfe60ff60408520541661130c565b60405163e1a7f11560e01b81526001600160a01b03918216918482600481865afa9182156109a5578592610d45575b5060a0820151169260608201516080830151926040810151906101e061018082015191015191604051956308bcf8b560e21b875285876004818b5afa968715610d3a578a97610cd2575b50916107ed610cbf927f78588744511143acc190289f68ddc549fe07f7dddd8165eb7a2650984a1a904c9894604051988998895288015260c0604088015260c087019061128f565b916080840152151560a08301520390a380f35b9650918587813d8311610d33575b610cea8183611189565b81010312610d2f576107ed610cbf92610d237f78588744511143acc190289f68ddc549fe07f7dddd8165eb7a2650984a1a904c9961136d565b98509250929092610c77565b8980fd5b503d610ce0565b6040513d8c823e3d90fd5b610d5a9192503d8087833e61018d8183611189565b9085610c2d565b823461087e57602036600319011261087e57610d7b61112a565b33825281602052610d9260ff60408420541661130c565b60405163e1a7f11560e01b8152906001600160a01b03908116908383600481855afa928315610e8c578493610e4e575b507f9b2a717d95b06db9955a19e12a89bc124b5cca5d3c03fdaca9a6c4f8c6aff1399060a084015116926060810151608082015191610e3c604082015191610e2e6101e0610180830151920151936040519687968752602087015260c0604087015260c086019061128f565b90848203606086015261128f565b9060808301528660a08301520390a380f35b7f9b2a717d95b06db9955a19e12a89bc124b5cca5d3c03fdaca9a6c4f8c6aff139919350610e85903d8087833e61018d8183611189565b9290610dc2565b6040513d86823e3d90fd5b823461087e57602036600319011261087e5760209060ff906040906001600160a01b03610ec261112a565b1681528084522054166040519015158152f35b823461087e576020806003193601126103d657610ef061112a565b90338352828152610f0760ff60408520541661130c565b6001600160a01b03918216835260018152604083208054908490556003545f199391929190848101908111610fc95785526002825280604086205416838652604086206001600160601b0360a01b9182825416179055600354858101908111610fb5579060019392918752600283526040872090815416905583865260408620541685525260408320556003548015610fa1570160035580f35b634e487b7160e01b83526011600452602483fd5b634e487b7160e01b87526011600452602487fd5b634e487b7160e01b86526011600452602486fd5b823461087e57602036600319011261087e57610ff761112a565b600454906001600160a01b039081831661107f578160065416330361102b5716906001600160601b0360a01b161760045580f35b60405162461bcd60e51b815260206004820152602660248201527f4f6e6c79206f776e65722063616e207365742061676772656761746f7220636f6044820152651b9d1c9858dd60d21b6064820152608490fd5b60405162461bcd60e51b815260206004820152600b60248201526a105b1c9958591e481cd95d60aa1b6044820152606490fd5b823461087e578060031936011261087e576006546040516001600160a01b039091168152602090f35b823461087e57602036600319011261087e57602090600435815260028252604060018060a01b0391205416604051908152f35b8390346103d657816003193601126103d6576020906003548152f35b600435906001600160a01b038216820361114057565b5f80fd5b67ffffffffffffffff811161115857604052565b634e487b7160e01b5f52604160045260245ffd5b610220810190811067ffffffffffffffff82111761115857604052565b90601f8019910116810190811067ffffffffffffffff82111761115857604052565b67ffffffffffffffff81116111585760051b60200190565b81601f82011215611140578035916111da836111ab565b926111e86040519485611189565b808452602092838086019260051b820101928311611140578301905b828210611212575050505090565b81358152908301908301611204565b81601f8201121561114057803591611238836111ab565b926112466040519485611189565b808452602092838086019260051b820101928311611140578301905b828210611270575050505090565b81356001600160a01b0381168103611140578152908301908301611262565b9081518082526020808093019301915f5b8281106112ae575050505090565b8351855293810193928101926001016112a0565b9081518082526020808093019301915f5b8281106112e1575050505090565b83516001600160a01b0316855293810193928101926001016112d3565b5f1981146103ba5760010190565b1561131357565b60405162461bcd60e51b815260206004820152601160248201527027b7363c903137b93937bb9037b93232b960791b6044820152606490fd5b919082018092116103ba57565b51906001600160a01b038216820361114057565b5190811515820361114057565b81601f8201121561114057805191611391836111ab565b9261139f6040519485611189565b808452602092838086019260051b820101928311611140578301905b8282106113c9575050505090565b815181529083019083016113bb565b81601f82011215611140578051916113ef836111ab565b926113fd6040519485611189565b808452602092838086019260051b820101928311611140578301905b828210611427575050505090565b83809161143384611359565b815201910190611419565b602091828282031261114057815167ffffffffffffffff928382116111405701916102208383031261114057604051936114778561116c565b61148084611359565b8552808401518281116111405784019083601f83011215611140578151916114a7836111ab565b926114b56040519485611189565b808452828085019160051b830101918683116111405783809101915b8383106115f05750505050850152604083015181811161114057826114f791850161137a565b6040850152606083015160608501526080830151608085015261151c60a08401611359565b60a085015260c083015181811161114057826115399185016113d8565b60c085015261154a60e08401611359565b60e085015261010061155d818501611359565b9085015261012061156f81850161136d565b9085015261014080840151908501526101608084015182811161114057836115989186016113d8565b908501526101809182840151918211611140576115b691840161137a565b908301526101a06115c8818301611359565b908301526101c080820151908301526101e08082015190830152610200809101519082015290565b81906115fb8461136d565b81520191019083906114d1565b805182101561161c5760209160051b010190565b634e487b7160e01b5f52603260045260245ffdfe60803461007f57601f61011138819003918201601f19168301916001600160401b038311848410176100835780849260209460405283398101031261007f57516001600160a01b038116810361007f577f6c2e6ad0697ee74b6b109859efe075280fbb8639fd0923b952c65a4373bc191855604051607990816100988239f35b5f80fd5b634e487b7160e01b5f52604160045260245ffdfe60806040527f6c2e6ad0697ee74b6b109859efe075280fbb8639fd0923b952c65a4373bc1918545f808092368280378136915af43d82803e15603f573d90f35b3d90fdfea2646970667358221220dc53c46fbbb536817120bbfe2ad4353676b0c05f64ede996df0aaa9938acc5ed64736f6c63430008140033a2646970667358221220a0aea8a2ae4ae859d00186bb7999a7fbfd1c816d2d54b03c0c0dcce4f3df5b8e64736f6c63430008140033000000000000000000000000d764a9550376b37f9184a0b9d0756b0f38f6bc44
Deployed Bytecode
0x6080806040526004361015610012575f80fd5b5f9060e0908235821c9081633ff1b8d61461110e575080636ba840b5146110db5780638da5cb5b146110b25780639967cf6014610fdd5780639ac6a87814610ed5578063a7401ce414610e97578063b148414c14610d61578063cadbe0e014610bcd578063d499a19314610b94578063e07cd799146103da5763e136703014610099575f80fd5b346103d65760403660031901126103d65760043590602435916003548084116103ce575b50808303918383116103ba576100d2836111ab565b926100e06040519485611189565b8084526100ef601f19916111ab565b01855b818110610334575050845b84610108848361134c565b10156101a6578061011b6004928561134c565b87526002602052604080882054905163e1a7f11560e01b815292889184919082906001600160a01b03165afa801561019b57610174928891610179575b506101638287611608565b5261016e8186611608565b506112fe565b6100fd565b61019591503d808a833e61018d8183611189565b81019061143e565b5f610158565b6040513d89823e3d90fd5b858285604051916020808401918185528351809352604085018260408560051b88010195019680925b8584106101dc5787870388f35b909192939495603f1988820301845285895191610220928382019360018060a01b0394858351168452848301519185850152815180915284610240850192019088905b8082106103185750505091816102d86102c461028161024e8897604060019b980151878203604089015261128f565b606080860151908701526080808601519087015260a08781870151169087015260c08086015190878303908801526112c2565b858a850151168a860152610100868186015116908601526101208085015115159086015261014080850151908601526101608085015190868303908701526112c2565b61018080840151908583039086015261128f565b926101a0908183015116908301526101c080820151908301526101e08082015190830152610200809101519101529a0194019401929795949391906101cf565b8251151584528c9693840193909201916001919091019061021f565b6020906040516103438161116c565b8881526060839080828401528060408401528a818401528a60808401528a60a08401528060c08401528a878401528a6101008401528a6101208401528a61014084015280610160840152610180830152896101a0830152896101c0830152896101e0830152896102008301528288010152016100f2565b634e487b7160e01b5f52601160045260245ffd5b92505f6100bd565b5080fd5b823461087e5761018036600319011261087e5760043567ffffffffffffffff81116103d657366023820112156103d657806004013591610419836111ab565b916104276040519384611189565b83835260208301906024829560051b82010190368211610b7357602401915b818310610b7b5750505060243567ffffffffffffffff81116103d6576104709036906004016111c3565b9060843567ffffffffffffffff81116103d657610491903690600401611221565b60a43591906001600160a01b03831683036103d65760c435151560c435036103d6576101043567ffffffffffffffff8111610b77576104d4903690600401611221565b956101243567ffffffffffffffff8111610b73576104f69036906004016111c3565b9661014435916001600160a01b0383168303610b6f5760c435610ad8575b8651845103610aa4578151845103610a6e578751845103610a37578851845103610a025761016435156109c457600554604051906001600160a01b031667ffffffffffffffff6101118301908111908311176109b0576101116116318339610111820152602081610111810103019086f080156109a5576004546001600160a01b0391821699911694893b156109a1579491939092869360206105de60405198899663d52604ff60e01b885260048801523360248801526101c060448801526101c48701906112c2565b6001600160a01b038b166064870152858103600319016084870152915180835291019590855b818110610983575050506106646106779161063785969760c435151560a48801526003198782030160c48801528c61128f565b9060443560e487015260643561010487015260e435610124870152600319868303016101448701526112c2565b838103600319016101648501528b61128f565b6001600160a01b03909116610184830152610164356101a4830152038183895af1801561097857610969575b50838152602081905260408120805460ff191660011790559060c435156108b4576001600160a01b0381163b156103d6576040516323b872dd60e01b81523360048201526001600160a01b038516602482015260e4356044820152828180606481010381836001600160a01b0387165af180156108a957908391610895575b505060206024915b6003548685526001835280604086205584526002825260408420866001600160601b0360a01b8254161790556107616003546112fe565b6003556040516370a0823160e01b81526004810187905292839182906001600160a01b03165afa918215610889578092610851575b5050610164351161081a57817f400ed65e0cf279c2660526497d8f603f1d86d78dfb01b019a0d337a105166e5d6107fb6020956107ed6040519560443587526064358988015260c0604088015260c087019061128f565b90858203606087015261128f565b92610164356080820152600160a08201528033940390a3604051908152f35b60405162461bcd60e51b815260206004820152600f60248201526e496e76616c69642062616c616e636560881b6044820152606490fd5b9091506020823d602011610881575b8161086d60209383611189565b8101031261087e5750518480610796565b80fd5b3d9150610860565b604051903d90823e3d90fd5b61089e90611144565b6103d6578186610722565b6040513d85823e3d90fd5b6040516323b872dd60e01b60208083019182523360248401526001600160a01b0387166044840152610164356064808501919091528352918491906108fa608482611189565b5190826001600160a01b0386165af11561095c5781513d61095357506001600160a01b0381163b155b61093157602060249161072a565b604051635274afe760e01b81526001600160a01b039091166004820152602490fd5b60011415610923565b50604051903d90823e3d90fd5b61097290611144565b856106a3565b6040513d84823e3d90fd5b8251151588526020978801978a975089965090920191600101610604565b8680fd5b6040513d87823e3d90fd5b634e487b7160e01b87526041600452602487fd5b60405162461bcd60e51b8152602060048201526016602482015275125b9d985b1a59081cdd185c9d195908185b5bdd5b9d60521b6044820152606490fd5b60405162461bcd60e51b815260206004820152600d60248201526c496e76616c696420726174696f60981b6044820152606490fd5b60405162461bcd60e51b815260206004820152600f60248201526e496e76616c6964206f7261636c657360881b6044820152606490fd5b60405162461bcd60e51b815260206004820152600e60248201526d092dcecc2d8d2c840d8cadccee8d60931b6044820152606490fd5b60405162461bcd60e51b815260206004820152600c60248201526b496e76616c6964204c54567360a01b6044820152606490fd5b60e43515610b315760016101643503156105145760405162461bcd60e51b815260206004820152601f60248201527f5374617274656420426f72726f7720416d6f756e74206d7573742062652031006044820152606490fd5b60405162461bcd60e51b81526020600482015260166024820152750526563656970742049442063616e6e6f7420626520360541b6044820152606490fd5b8480fd5b8380fd5b8280fd5b82358015158103610b6f57815260209283019201610446565b823461087e57602036600319011261087e576020906040906001600160a01b03610bbc61112a565b168152600183522054604051908152f35b823461087e576020806003193601126103d657610be861112a565b338352828252610bfe60ff60408520541661130c565b60405163e1a7f11560e01b81526001600160a01b03918216918482600481865afa9182156109a5578592610d45575b5060a0820151169260608201516080830151926040810151906101e061018082015191015191604051956308bcf8b560e21b875285876004818b5afa968715610d3a578a97610cd2575b50916107ed610cbf927f78588744511143acc190289f68ddc549fe07f7dddd8165eb7a2650984a1a904c9894604051988998895288015260c0604088015260c087019061128f565b916080840152151560a08301520390a380f35b9650918587813d8311610d33575b610cea8183611189565b81010312610d2f576107ed610cbf92610d237f78588744511143acc190289f68ddc549fe07f7dddd8165eb7a2650984a1a904c9961136d565b98509250929092610c77565b8980fd5b503d610ce0565b6040513d8c823e3d90fd5b610d5a9192503d8087833e61018d8183611189565b9085610c2d565b823461087e57602036600319011261087e57610d7b61112a565b33825281602052610d9260ff60408420541661130c565b60405163e1a7f11560e01b8152906001600160a01b03908116908383600481855afa928315610e8c578493610e4e575b507f9b2a717d95b06db9955a19e12a89bc124b5cca5d3c03fdaca9a6c4f8c6aff1399060a084015116926060810151608082015191610e3c604082015191610e2e6101e0610180830151920151936040519687968752602087015260c0604087015260c086019061128f565b90848203606086015261128f565b9060808301528660a08301520390a380f35b7f9b2a717d95b06db9955a19e12a89bc124b5cca5d3c03fdaca9a6c4f8c6aff139919350610e85903d8087833e61018d8183611189565b9290610dc2565b6040513d86823e3d90fd5b823461087e57602036600319011261087e5760209060ff906040906001600160a01b03610ec261112a565b1681528084522054166040519015158152f35b823461087e576020806003193601126103d657610ef061112a565b90338352828152610f0760ff60408520541661130c565b6001600160a01b03918216835260018152604083208054908490556003545f199391929190848101908111610fc95785526002825280604086205416838652604086206001600160601b0360a01b9182825416179055600354858101908111610fb5579060019392918752600283526040872090815416905583865260408620541685525260408320556003548015610fa1570160035580f35b634e487b7160e01b83526011600452602483fd5b634e487b7160e01b87526011600452602487fd5b634e487b7160e01b86526011600452602486fd5b823461087e57602036600319011261087e57610ff761112a565b600454906001600160a01b039081831661107f578160065416330361102b5716906001600160601b0360a01b161760045580f35b60405162461bcd60e51b815260206004820152602660248201527f4f6e6c79206f776e65722063616e207365742061676772656761746f7220636f6044820152651b9d1c9858dd60d21b6064820152608490fd5b60405162461bcd60e51b815260206004820152600b60248201526a105b1c9958591e481cd95d60aa1b6044820152606490fd5b823461087e578060031936011261087e576006546040516001600160a01b039091168152602090f35b823461087e57602036600319011261087e57602090600435815260028252604060018060a01b0391205416604051908152f35b8390346103d657816003193601126103d6576020906003548152f35b600435906001600160a01b038216820361114057565b5f80fd5b67ffffffffffffffff811161115857604052565b634e487b7160e01b5f52604160045260245ffd5b610220810190811067ffffffffffffffff82111761115857604052565b90601f8019910116810190811067ffffffffffffffff82111761115857604052565b67ffffffffffffffff81116111585760051b60200190565b81601f82011215611140578035916111da836111ab565b926111e86040519485611189565b808452602092838086019260051b820101928311611140578301905b828210611212575050505090565b81358152908301908301611204565b81601f8201121561114057803591611238836111ab565b926112466040519485611189565b808452602092838086019260051b820101928311611140578301905b828210611270575050505090565b81356001600160a01b0381168103611140578152908301908301611262565b9081518082526020808093019301915f5b8281106112ae575050505090565b8351855293810193928101926001016112a0565b9081518082526020808093019301915f5b8281106112e1575050505090565b83516001600160a01b0316855293810193928101926001016112d3565b5f1981146103ba5760010190565b1561131357565b60405162461bcd60e51b815260206004820152601160248201527027b7363c903137b93937bb9037b93232b960791b6044820152606490fd5b919082018092116103ba57565b51906001600160a01b038216820361114057565b5190811515820361114057565b81601f8201121561114057805191611391836111ab565b9261139f6040519485611189565b808452602092838086019260051b820101928311611140578301905b8282106113c9575050505090565b815181529083019083016113bb565b81601f82011215611140578051916113ef836111ab565b926113fd6040519485611189565b808452602092838086019260051b820101928311611140578301905b828210611427575050505090565b83809161143384611359565b815201910190611419565b602091828282031261114057815167ffffffffffffffff928382116111405701916102208383031261114057604051936114778561116c565b61148084611359565b8552808401518281116111405784019083601f83011215611140578151916114a7836111ab565b926114b56040519485611189565b808452828085019160051b830101918683116111405783809101915b8383106115f05750505050850152604083015181811161114057826114f791850161137a565b6040850152606083015160608501526080830151608085015261151c60a08401611359565b60a085015260c083015181811161114057826115399185016113d8565b60c085015261154a60e08401611359565b60e085015261010061155d818501611359565b9085015261012061156f81850161136d565b9085015261014080840151908501526101608084015182811161114057836115989186016113d8565b908501526101809182840151918211611140576115b691840161137a565b908301526101a06115c8818301611359565b908301526101c080820151908301526101e08082015190830152610200809101519082015290565b81906115fb8461136d565b81520191019083906114d1565b805182101561161c5760209160051b010190565b634e487b7160e01b5f52603260045260245ffdfe60803461007f57601f61011138819003918201601f19168301916001600160401b038311848410176100835780849260209460405283398101031261007f57516001600160a01b038116810361007f577f6c2e6ad0697ee74b6b109859efe075280fbb8639fd0923b952c65a4373bc191855604051607990816100988239f35b5f80fd5b634e487b7160e01b5f52604160045260245ffdfe60806040527f6c2e6ad0697ee74b6b109859efe075280fbb8639fd0923b952c65a4373bc1918545f808092368280378136915af43d82803e15603f573d90f35b3d90fdfea2646970667358221220dc53c46fbbb536817120bbfe2ad4353676b0c05f64ede996df0aaa9938acc5ed64736f6c63430008140033a2646970667358221220a0aea8a2ae4ae859d00186bb7999a7fbfd1c816d2d54b03c0c0dcce4f3df5b8e64736f6c63430008140033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000d764a9550376b37f9184a0b9d0756b0f38f6bc44
-----Decoded View---------------
Arg [0] : _implementationContract (address): 0xD764A9550376b37F9184a0b9d0756b0f38F6bC44
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 000000000000000000000000d764a9550376b37f9184a0b9d0756b0f38f6bc44
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 31 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.