Created
September 3, 2025 07:04
-
-
Save cNoveron/b7213aeba0c453bda0ebe12cd3e98e83 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| pragma solidity ^0.5.16; | |
| pragma experimental ABIEncoderV2; | |
| import "./XToken.sol"; | |
| /** | |
| * @title Lendexe's xNativeToken Contract | |
| * @notice XToken which wraps Iota | |
| * @author Lendexe | |
| */ | |
| contract XNativeToken is XToken { | |
| /** | |
| * @notice Construct a new xNativeToken money market | |
| * @param comptroller_ The address of the Comptroller | |
| * @param interestRateModel_ The address of the interest rate model | |
| * @param initialExchangeRateMantissa_ The initial exchange rate, scaled by 1e18 | |
| * @param name_ ERC-20 name of this token | |
| * @param symbol_ ERC-20 symbol of this token | |
| * @param decimals_ ERC-20 decimal precision of this token | |
| * @param admin_ Address of the administrator of this token | |
| */ | |
| constructor( | |
| ComptrollerInterface comptroller_, | |
| InterestRateModel interestRateModel_, | |
| uint256 initialExchangeRateMantissa_, | |
| string memory name_, | |
| string memory symbol_, | |
| uint8 decimals_, | |
| address payable admin_ | |
| ) public { | |
| // Creator of the contract is admin during initialization | |
| admin = msg.sender; | |
| initialize( | |
| comptroller_, | |
| interestRateModel_, | |
| initialExchangeRateMantissa_, | |
| name_, | |
| symbol_, | |
| decimals_ | |
| ); | |
| // Set the proper admin now that initialization is done | |
| admin = admin_; | |
| } | |
| mapping(address => uint256) private lastBorrowAmount; | |
| /*** User Interface ***/ | |
| /** | |
| * @notice Sender supplies assets into the market and receives xTokens in exchange | |
| * @dev Reverts upon any failure | |
| */ | |
| function mint() external payable { | |
| (uint256 err, ) = mintInternal(msg.value); | |
| requireNoError(err, "mint failed"); | |
| } | |
| /** | |
| * @notice Sender redeems xTokens in exchange for the underlying asset | |
| * @dev Accrues interest whether or not the operation succeeds, unless reverted | |
| * @param redeemTokens The number of xTokens to redeem into underlying | |
| * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details) | |
| */ | |
| function redeem(uint256 redeemTokens) external returns (uint256) { | |
| return redeemInternal(redeemTokens); | |
| } | |
| /** | |
| * @notice Sender redeems xTokens in exchange for a specified amount of underlying asset | |
| * @dev Accrues interest whether or not the operation succeeds, unless reverted | |
| * @param redeemAmount The amount of underlying to redeem | |
| * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details) | |
| */ | |
| function redeemUnderlying(uint256 redeemAmount) external returns (uint256) { | |
| return redeemUnderlyingInternal(redeemAmount); | |
| } | |
| /** | |
| * @notice Sender borrows assets from the protocol to their own address | |
| * @param borrowAmount The amount of the underlying asset to borrow | |
| * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details) | |
| */ | |
| function borrow(uint256 borrowAmount) external returns (uint256) { | |
| lastBorrowAmount[msg.sender] = borrowAmount; | |
| return borrowInternal(borrowAmount); | |
| } | |
| function getBorrowAmount(address user) external view returns (uint256) { | |
| return lastBorrowAmount[user]; | |
| } | |
| /** | |
| * @notice Sender repays their own borrow | |
| * @dev Reverts upon any failure | |
| */ | |
| function repayBorrow() external payable { | |
| (uint256 err, ) = repayBorrowInternal(msg.value); | |
| requireNoError(err, "repayBorrow failed"); | |
| } | |
| /** | |
| * @notice Sender repays a borrow belonging to borrower | |
| * @dev Reverts upon any failure | |
| * @param borrower the account with the debt being payed off | |
| */ | |
| function repayBorrowBehalf(address borrower) external payable { | |
| (uint256 err, ) = repayBorrowBehalfInternal(borrower, msg.value); | |
| requireNoError(err, "repayBorrowBehalf failed"); | |
| } | |
| /** | |
| * @notice The sender liquidates the borrowers collateral. | |
| * The collateral seized is transferred to the liquidator. | |
| * @dev Reverts upon any failure | |
| * @param borrower The borrower of this xToken to be liquidated | |
| * @param xTokenCollateral The market in which to seize collateral from the borrower | |
| */ | |
| function liquidateBorrow(address borrower, XToken xTokenCollateral) | |
| external | |
| payable | |
| { | |
| require(msg.sender == comptroller.liquidatorAddress(), "Only liquidator set by admin can liquidate!"); | |
| (uint256 err, ) = liquidateBorrowInternal( | |
| borrower, | |
| msg.value, | |
| xTokenCollateral | |
| ); | |
| requireNoError(err, "liquidateBorrow failed"); | |
| } | |
| /** | |
| * @notice The sender adds to reserves. | |
| * @return uint 0=success, otherwise a failure (see ErrorReporter.sol for details) | |
| */ | |
| function _addReserves() external payable returns (uint256) { | |
| return _addReservesInternal(msg.value); | |
| } | |
| /** | |
| * @notice Send Iota to xNativeToken to mint | |
| */ | |
| function() external payable { | |
| (uint256 err, ) = mintInternal(msg.value); | |
| requireNoError(err, "mint failed"); | |
| } | |
| /*** Safe Token ***/ | |
| /** | |
| * @notice Gets balance of this contract in terms of Iota, before this message | |
| * @dev This excludes the value of the current message, if any | |
| * @return The quantity of Iota owned by this contract | |
| */ | |
| function getCashPrior() internal view returns (uint256) { | |
| (MathError err, uint256 startingBalance) = subUInt( | |
| address(this).balance, | |
| msg.value | |
| ); | |
| require(err == MathError.NO_ERROR); | |
| return startingBalance; | |
| } | |
| /** | |
| * @notice Gets decimal number of the underlying token | |
| * @return The decimal number of the underlying token | |
| */ | |
| function getUnderlyingDecimalsNumber() internal view returns (uint8) { | |
| return decimals; | |
| } | |
| /** | |
| * @notice Perform the actual transfer in, which is a no-op | |
| * @param from Address sending the Iota | |
| * @param amount Amount of Iota being sent | |
| * @return The actual amount of Iota transferred | |
| */ | |
| function doTransferIn(address from, uint256 amount) | |
| internal | |
| returns (uint256) | |
| { | |
| // Sanity checks | |
| require(msg.sender == from, "sender mismatch"); | |
| require(msg.value == amount, "value mismatch"); | |
| return amount; | |
| } | |
| function doTransferOut(address payable to, uint256 amount) internal { | |
| /* Send the Iota, with minimal gas and revert on failure */ | |
| to.transfer(amount); | |
| } | |
| function requireNoError(uint256 errCode, string memory message) | |
| internal | |
| pure | |
| { | |
| if (errCode == uint256(Error.NO_ERROR)) { | |
| return; | |
| } | |
| bytes memory fullMessage = new bytes(bytes(message).length + 5); | |
| uint256 i; | |
| for (i = 0; i < bytes(message).length; i++) { | |
| fullMessage[i] = bytes(message)[i]; | |
| } | |
| fullMessage[i + 0] = bytes1(uint8(32)); | |
| fullMessage[i + 1] = bytes1(uint8(40)); | |
| fullMessage[i + 2] = bytes1(uint8(48 + (errCode / 10))); | |
| fullMessage[i + 3] = bytes1(uint8(48 + (errCode % 10))); | |
| fullMessage[i + 4] = bytes1(uint8(41)); | |
| require(errCode == uint256(Error.NO_ERROR), string(fullMessage)); | |
| } | |
| function approveUnderlying(address spender, uint256 amount) internal { | |
| return; | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment