Address
0xf509c2d4cbc4312653e96d91d2948e83a9700a77Current Holdings
$0.00
TXs sent
0
First Active
2025-10-23
block 24,832,676
Last Active
12 days ago
block 27,462,421
Funded By
not identified
Net worth historyi
No net-worth snapshots recorded yet
exact matchXSDStablecoinsolc 0.8.20+commit.a1b79de6runtime exact · creation exact
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity ^0.8.0;
import "../ERC20/ERC20Custom.sol";
import "./Pools/Interfaces/IXSDWETHpool.sol";
import "./Pools/Interfaces/IBankXWETHpool.sol";
import "./Pools/Interfaces/ICollateralPool.sol";
import "@openzeppelin/contracts/utils/Context.sol";
import "../Oracle/ChainlinkPLSUSDPriceConsumer.sol";
import "../Oracle/ChainlinkXAGUSDPriceConsumer.sol";
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
contract XSDStablecoin is ERC20Custom {
/* ========== STATE VARIABLES ========== */
enum PriceChoice { XSD, BankX }
ChainlinkPLSUSDPriceConsumer private eth_usd_pricer;
ChainlinkXAGUSDPriceConsumer private xag_usd_pricer;
uint8 private eth_usd_pricer_decimals;
uint8 private xag_usd_pricer_decimals;
string public symbol;
string public name;
uint8 public constant decimals = 18;
address public treasury;
address public collateral_pool_address;
address public router;
address public eth_usd_oracle_address;
address public xag_usd_oracle_address;
address public smartcontract_owner;
IBankXWETHpool private bankxEthPool;
IXSDWETHpool private xsdEthPool;
uint256 public cap_rate;
uint256 public genesis_supply;
// The addresses in this array are added by the oracle and these contracts are able to mint xsd
address[] public xsd_pools_array;
// Mapping is also used for faster verification
mapping(address => bool) public xsd_pools;
// Constants for various precisions
uint256 private constant PRICE_PRECISION = 1e6;
/* ========== MODIFIERS ========== */
modifier onlyPools() {
require(xsd_pools[msg.sender] == true, "Only xsd pools can call this function");
_;//check happens before the function is executed
}
modifier onlyByOwner(){
require(msg.sender == smartcontract_owner, "You are not the owner");
_;
}
modifier onlyByOwnerOrPool() {
require(
msg.sender == smartcontract_owner
|| xsd_pools[msg.sender] == true,
"You are not the owner or a pool");
_;
}
/* ========== CONSTRUCTOR ========== */
constructor(
string memory _name,
string memory _symbol,
uint256 _pool_amount,
uint256 _genesis_supply,
address _smartcontract_owner,
address _treasury,
uint256 _cap_rate
) {
require((_smartcontract_owner != address(0))
&& (_treasury != address(0)), "Zero address detected");
name = _name;
symbol = _symbol;
genesis_supply = _genesis_supply + _pool_amount;
treasury = _treasury;
_mint(_smartcontract_owner, _pool_amount);
_mint(treasury, _genesis_supply);
smartcontract_owner = _smartcontract_owner;
cap_rate = _cap_rate;// Maximum mint amount
}
/* ========== VIEWS ========== */
function eth_usd_price() public view returns (uint256) {
return (uint256(eth_usd_pricer.getLatestPrice())*PRICE_PRECISION)/(uint256(10) ** eth_usd_pricer_decimals);
}
//silver price
//hard coded value for testing on goerli
function xag_usd_price() public view returns (uint256) {
return (uint256(xag_usd_pricer.getLatestPrice())*PRICE_PRECISION)/(uint256(10) ** xag_usd_pricer_decimals);
}
/* ========== PUBLIC FUNCTIONS ========== */
function creatorMint(uint256 amount) public onlyByOwner{
require(genesis_supply+amount<cap_rate,"cap limit reached");
super._mint(treasury,amount);
}
/* ========== RESTRICTED FUNCTIONS ========== */
// Used by pools when user redeems
function pool_burn_from(address b_address, uint256 b_amount) public onlyPools {
super._burnFrom(b_address, b_amount);
emit XSDBurned(b_address, msg.sender, b_amount);
}
// This function is what other xsd pools will call to mint new XSD
function pool_mint(address m_address, uint256 m_amount) public onlyPools {
super._mint(m_address, m_amount);
emit XSDMinted(msg.sender, m_address, m_amount);
}
// Adds collateral addresses supported, such as tether and busd, must be ERC20
function addPool(address pool_address) public onlyByOwner {
require(pool_address != address(0), "Zero address detected");
require(xsd_pools[pool_address] == false, "Address already exists");
xsd_pools[pool_address] = true;
xsd_pools_array.push(pool_address);
emit PoolAdded(pool_address);
}
// Remove a pool
function removePool(address pool_address) public onlyByOwner {
require(pool_address != address(0), "Zero address detected");
require(xsd_pools[pool_address] == true, "Address nonexistant");
// Delete from the mapping
delete xsd_pools[pool_address];
// 'Delete' from the array by setting the address to 0x0
for (uint i = 0; i < xsd_pools_array.length; i++){
if (xsd_pools_array[i] == pool_address) {
xsd_pools_array[i] = address(0); // This will leave a null in the array and keep the indices the same
break;
}
}
emit PoolRemoved(pool_address);
}
// create a seperate function for users and the pool
function burnpoolXSD(uint _xsdamount) public {
require(msg.sender == router, "Only the router can access this function");
require(totalSupply()-ICollateralPool(payable(collateral_pool_address)).collat_XSD()>_xsdamount, "uXSD has to be positive");
super._burn(address(xsdEthPool),_xsdamount);
xsdEthPool.sync();
emit XSDBurned(msg.sender, address(this), _xsdamount);
}
// add burn function for users
function burnUserXSD(uint _xsdamount) public {
require(totalSupply()-ICollateralPool(payable(collateral_pool_address)).collat_XSD()>_xsdamount, "uXSD has to be positive");
super._burn(msg.sender, _xsdamount);
emit XSDBurned(msg.sender, address(this), _xsdamount);
}
function setTreasury(address _new_treasury) public onlyByOwner {
require(_new_treasury != address(0), "Zero address detected");
treasury = _new_treasury;
}
function setETHUSDOracle(address _eth_usd_oracle_address) public onlyByOwner {
require(_eth_usd_oracle_address != address(0), "Zero address detected");
eth_usd_oracle_address = _eth_usd_oracle_address;
eth_usd_pricer = ChainlinkPLSUSDPriceConsumer(eth_usd_oracle_address);
eth_usd_pricer_decimals = eth_usd_pricer.getDecimals();
emit ETHUSDOracleSet(_eth_usd_oracle_address);
}
function setXAGUSDOracle(address _xag_usd_oracle_address) public onlyByOwner {
require(_xag_usd_oracle_address != address(0), "Zero address detected");
xag_usd_oracle_address = _xag_usd_oracle_address;
xag_usd_pricer = ChainlinkXAGUSDPriceConsumer(xag_usd_oracle_address);
xag_usd_pricer_decimals = xag_usd_pricer.getDecimals();
emit XAGUSDOracleSet(_xag_usd_oracle_address);
}
function setRouterAddress(address _router) external onlyByOwner {
require(_router != address(0), "Zero address detected");
router = _router;
}
// Sets the XSD_ETH Uniswap oracle address
function setXSDEthPool(address _xsd_pool_addr) public onlyByOwner {
require(_xsd_pool_addr != address(0), "Zero address detected");
xsdEthPool = IXSDWETHpool(_xsd_pool_addr);
emit XSDETHPoolSet(_xsd_pool_addr);
}
// Sets the BankX_ETH Uniswap oracle address
function setBankXEthPool(address _bankx_pool_addr) public onlyByOwner {
require(_bankx_pool_addr != address(0), "Zero address detected");
bankxEthPool = IBankXWETHpool(_bankx_pool_addr);
emit BankXEthPoolSet(_bankx_pool_addr);
}
//sets the collateral pool address
function setCollateralEthPool(address _collateral_pool_address) public onlyByOwner {
require(_collateral_pool_address != address(0), "Zero address detected");
collateral_pool_address = payable(_collateral_pool_address);
}
function setSmartContractOwner(address _smartcontract_owner) external{
require(msg.sender == smartcontract_owner, "Only the smart contract owner can access this function");
require(_smartcontract_owner != address(0), "Zero address detected");
smartcontract_owner = _smartcontract_owner;
}
function renounceOwnership() external{
require(msg.sender == smartcontract_owner, "Only the smart contract owner can access this function");
smartcontract_owner = address(0);
}
/* ========== EVENTS ========== */
// Track XSD burned
event XSDBurned(address indexed from, address indexed to, uint256 amount);
// Track XSD minted
event XSDMinted(address indexed from, address indexed to, uint256 amount);
event PoolAdded(address pool_address);
event PoolRemoved(address pool_address);
event RedemptionFeeSet(uint256 red_fee);
event MintingFeeSet(uint256 min_fee);
event ETHUSDOracleSet(address eth_usd_oracle_address);
event XAGUSDOracleSet(address xag_usd_oracle_address);
event XSDETHPoolSet(address xsd_pool_addr);
event BankXEthPoolSet(address bankx_pool_addr);
}