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": {
"src/USDS2USDC2DAI.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.25;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {IDssLitePsm} from "./interfaces/IDssLitePsm.sol";
import {IDaiUsds} from "./interfaces/IDaiUsds.sol";
contract USDS2USDC2DAI {
IERC20 public constant USDC = IERC20(0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48);
IERC20 public constant USDS = IERC20(0xdC035D45d973E3EC169d2276DDab16f1e407384F);
IERC20 public constant DAI = IERC20(0x6B175474E89094C44Da98b954EedeAC495271d0F);
//usdc<<->>dai
IDssLitePsm public constant DssLitePsm = IDssLitePsm(0xf6e72Db5454dd049d0788e411b06CfAF16853042);
//dai<<->>usds
IDaiUsds public constant DaiUsds = IDaiUsds(0x3225737a9Bbb6473CB4a45b7244ACa2BeFdB276A);
event Usdc2Usds(address usr, uint256 usdsAmount, uint256 usdcAmount);
event Usds2Usdc(address usr, uint256 usdsAmount, uint256 usdcAmount);
event Usdc2Dai(address usr, uint256 usdsAmount, uint256 daiAmount);
event Dai2Usdc(address usr, uint256 daiAmount, uint256 usdcAmount);
event Usds2Dai(address usr, uint256 usdsAmount, uint256 daiAmount);
event Dai2Usds(address usr, uint256 daiAmount, uint256 usdsAmount);
function usdc2usds(uint256 _fromAmount) external returns (uint256) {
// usdc->dai
USDC.transferFrom(msg.sender, address(this), _fromAmount);
USDC.approve(address(DssLitePsm), _fromAmount);
DssLitePsm.sellGem(address(this), _fromAmount);
// dai->usds
uint256 daiAmount_ = DAI.balanceOf(address(this));
DAI.approve(address(DaiUsds), daiAmount_);
DaiUsds.daiToUsds(address(this), daiAmount_);
uint256 usdsAmount_ = USDS.balanceOf(address(this));
USDS.transfer(msg.sender, usdsAmount_);
emit Usds2Usdc(msg.sender, _fromAmount, usdsAmount_);
return usdsAmount_;
}
function usds2usdc(uint256 _fromAmount) external returns (uint256) {
// usds->dai
USDS.transferFrom(msg.sender, address(this), _fromAmount);
USDS.approve(address(DaiUsds), _fromAmount);
DaiUsds.usdsToDai(address(this), _fromAmount);
// dai->usdc
uint256 daiAmount_ = DAI.balanceOf(address(this));
DAI.approve(address(DssLitePsm), daiAmount_);
DssLitePsm.buyGem(address(this), daiAmount_ / 1e12);
uint256 usdcAmount_ = USDC.balanceOf(address(this));
USDC.transfer(msg.sender, usdcAmount_);
emit Usds2Usdc(msg.sender, _fromAmount, usdcAmount_);
return usdcAmount_;
}
function usdc2dai(uint256 _fromAmount) external returns (uint256) {
// usdc->dai
USDC.transferFrom(msg.sender, address(this), _fromAmount);
USDC.approve(address(DssLitePsm), _fromAmount);
DssLitePsm.sellGem(address(this), _fromAmount);
uint256 daiAmount_ = DAI.balanceOf(address(this));
DAI.transfer(msg.sender, daiAmount_);
emit Usdc2Dai(msg.sender, _fromAmount, daiAmount_);
return daiAmount_;
}
function dai2usdc(uint256 _fromAmount) external returns (uint256) {
// dai->usdc
DAI.transferFrom(msg.sender, address(this), _fromAmount);
DAI.approve(address(DssLitePsm), _fromAmount);
DssLitePsm.buyGem(address(this), _fromAmount / 1e12);
uint256 usdcAmount_ = USDC.balanceOf(address(this));
USDC.transfer(msg.sender, usdcAmount_);
emit Dai2Usdc(msg.sender, _fromAmount, usdcAmount_);
return usdcAmount_;
}
function usds2dai(uint256 _fromAmount) external returns (uint256) {
// usds->dai
USDS.transferFrom(msg.sender, address(this), _fromAmount);
USDS.approve(address(DaiUsds), _fromAmount);
DaiUsds.usdsToDai(address(this), _fromAmount);
uint256 daiAmount_ = DAI.balanceOf(address(this));
DAI.transfer(msg.sender, daiAmount_);
emit Usds2Dai(msg.sender, _fromAmount, daiAmount_);
return daiAmount_;
}
function dai2usds(uint256 _fromAmount) external returns (uint256) {
// dai->usds
DAI.transferFrom(msg.sender, address(this), _fromAmount);
DAI.approve(address(DaiUsds), _fromAmount);
DaiUsds.daiToUsds(address(this), _fromAmount);
uint256 usdsAmount_ = USDS.balanceOf(address(this));
USDS.transfer(msg.sender, usdsAmount_);
emit Dai2Usds(msg.sender, _fromAmount, usdsAmount_);
return usdsAmount_;
}
}"
},
"lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol": {
"content": "// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (token/ERC20/IERC20.sol)
pragma solidity >=0.4.16;
/**
* @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);
}
"
},
"src/interfaces/IDssLitePsm.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.25;
interface IDssLitePsm {
//dai->usdc
function buyGem(address usr, uint256 gemAmt) external returns (uint256 daiInWad);
//usdc->dai
function sellGem(address usr, uint256 gemAmt) external returns (uint256 daiOutWad);
}
"
},
"src/interfaces/IDaiUsds.sol": {
"content": "// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.25;
interface IDaiUsds {
function daiToUsds(address usr, uint256 wad) external;
function usdsToDai(address usr, uint256 wad) external;
}
"
}
},
"settings": {
"remappings": [
"@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/",
"@openzeppelin/contracts/=lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/",
"erc4626-tests/=lib/openzeppelin-contracts-upgradeable/lib/erc4626-tests/",
"forge-std/=lib/forge-std/src/",
"halmos-cheatcodes/=lib/openzeppelin-contracts-upgradeable/lib/halmos-cheatcodes/src/",
"openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/",
"openzeppelin-contracts/=lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/"
],
"optimizer": {
"enabled": false,
"runs": 200
},
"metadata": {
"useLiteralContent": false,
"bytecodeHash": "ipfs",
"appendCBOR": true
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"evmVersion": "prague",
"viaIR": false
}
}}
Submitted on: 2025-09-19 12:06:40
Comments
Log in to comment.
No comments yet.