Description:
ERC20 token contract with Factory capabilities. Standard implementation for fungible tokens on Ethereum.
Blockchain: Ethereum
Source Code: View Code On The Blockchain
Solidity Source Code:
{{
"language": "Solidity",
"sources": {
"@openzeppelin/contracts/token/ERC20/IERC20.sol": {
"content": "// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/IERC20.sol)
pragma solidity ^0.8.20;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
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);
}
"
},
"contracts/helpers/ReservoirHelper.sol": {
"content": "// SPDX-License-Identifier: MIT
pragma solidity 0.8.24;
pragma abicoder v1;
import "../interfaces/Reservoir.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
/**
* @title ReservoirHelper
* @notice Helper that performs onchain calculation required to call a Reservoir contract and returns corresponding caller and data
*/
contract ReservoirHelper {
function swapRUSD(
uint256 amountIn,
ICreditEnforcer creditEnforcerAddress,
IPegStabilityModule psmAddress,
bool isRedeem,
uint256 decimal_factor
) external pure returns (address target, address sourceTokenInteractionTarget, uint256 actualSwapAmount, bytes memory data) {
if (isRedeem) {
bytes memory resultData = abi.encodeCall(psmAddress.redeem, (amountIn / 10 ** (18 - decimal_factor) ));
return (address(psmAddress), address(psmAddress), amountIn, resultData);
} else {
bytes memory resultData = abi.encodeCall(creditEnforcerAddress.mintStablecoin, (amountIn));
return (address(creditEnforcerAddress), address(psmAddress), amountIn, resultData);
}
}
function swapSRUSD(
uint256 amountIn,
ICreditEnforcer creditEnforcerAddress,
ISavingsModule smAddress,
bool isRedeem
) external view returns (address target, address sourceTokenInteractionTarget, uint256 actualSwapAmount, bytes memory data) {
if (isRedeem) {
// This calculation is an inversion of the formula used in SavingsModule.redeem:
// srusd.burnFrom(from, (burnAmount * (1e6 + redeemFee)) / 1e6);
uint256 burnAmount = _ceilDiv(amountIn * 1e6, 1e6 + smAddress.redeemFee());
// Amount is the inversion of the following formula:
// Math.ceilDiv(amount * 1e8, _currentPrice());
bytes memory resultData = abi.encodeCall(smAddress.redeem, (burnAmount * smAddress.currentPrice() / 1e8));
return (address(smAddress), address(smAddress), amountIn, resultData);
} else {
bytes memory resultData = abi.encodeCall(creditEnforcerAddress.mintSavingcoin, (amountIn));
return (address(creditEnforcerAddress), address(smAddress), amountIn, resultData);
}
}
/**
* @dev Returns the ceiling of the division of two numbers.
*
* This differs from standard division with `/` in that it rounds up instead
* of rounding down.
*/
function _ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
// (a + b - 1) / b can overflow on addition, so we distribute.
return a == 0 ? 0 : (a - 1) / b + 1;
}
}
"
},
"contracts/interfaces/Reservoir.sol": {
"content": "// SPDX-License-Identifier: GPL-3.0-only
pragma solidity 0.8.24;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
interface ICreditEnforcer {
function mintStablecoin(uint256 amount) external returns (uint256);
function mintSavingcoin(uint256 amount) external returns (uint256);
}
interface IPegStabilityModule {
function redeem(uint256 amount) external;
}
interface ISavingsModule {
function redeem(uint256 amount) external;
function currentPrice() external view returns (uint256);
function redeemFee() external view returns (uint256);
}
"
}
},
"settings": {
"optimizer": {
"enabled": true,
"runs": 1000000
},
"evmVersion": "cancun",
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"metadata": {
"useLiteralContent": true
}
}
}}
Submitted on: 2025-10-07 17:28:42
Comments
Log in to comment.
No comments yet.