ERC20
This contract is an ERC20 token.
Name
Frax
Symbol
FRAX
Decimals
18
Total Supply
233,401,757 FRAX
About
link
description
Frax (FRAX) is a cryptocurrency and operates on the Ethereum platform. Frax has a current supply of 233,401,756.79685092. The last known price of Frax is 0.99572113 USD and is up -0.00 over the last 24 hours. It is currently trading on 21 active market(s) with $5,727,296.64 traded over the last 24 hours. More information can be found at https://frax.finance/#welcome.
Identical Contracts
The following contracts have identical source code.
Stats
Public Functions
41
Event Types
7
Code Size
313,011 bytes
Library Use
Uses SafeMath for uint256.
Events (7) keyboard_arrow_up
Constants (5) keyboard_arrow_up
State Variables (31) keyboard_arrow_up
Functions
hasRole keyboard_arrow_up
getRoleMemberCount keyboard_arrow_up
getRoleMember keyboard_arrow_up
getRoleAdmin keyboard_arrow_up
grantRole keyboard_arrow_up
Requirements help
null
Source Code
function grantRole(bytes32 role, address account) public virtual {
require(
hasRole(_roles[role].adminRole, _msgSender()),
"AccessControl: sender must be an admin to grant"
);
_grantRole(role, account);
}
revokeRole keyboard_arrow_up
Requirements help
null
Source Code
function revokeRole(bytes32 role, address account) public virtual {
require(
hasRole(_roles[role].adminRole, _msgSender()),
"AccessControl: sender must be an admin to revoke"
);
_revokeRole(role, account);
}
renounceRole keyboard_arrow_up
Requirements help
Source Code
function renounceRole(bytes32 role, address account) public virtual {
require(
account == _msgSender(),
"AccessControl: can only renounce roles for self"
);
_revokeRole(role, account);
}
totalSupply keyboard_arrow_up
balanceOf keyboard_arrow_up
transfer keyboard_arrow_up
Requirements help
Source Code
function transfer(address recipient, uint256 amount)
public
virtual
override
returns (bool)
{
_transfer(_msgSender(), recipient, amount);
return true;
}
allowance keyboard_arrow_up
approve keyboard_arrow_up
Requirements help
Source Code
function approve(address spender, uint256 amount)
public
virtual
override
returns (bool)
{
_approve(_msgSender(), spender, amount);
return true;
}
transferFrom keyboard_arrow_up
Requirements help
Source Code
function transferFrom(
address sender,
address recipient,
uint256 amount
) public virtual override returns (bool) {
_transfer(sender, recipient, amount);
_approve(
sender,
_msgSender(),
_allowances[sender][_msgSender()].sub(
amount,
"ERC20: transfer amount exceeds allowance"
)
);
return true;
}
increaseAllowance keyboard_arrow_up
Requirements help
Source Code
function increaseAllowance(address spender, uint256 addedValue)
public
virtual
returns (bool)
{
_approve(
_msgSender(),
spender,
_allowances[_msgSender()][spender].add(addedValue)
);
return true;
}
decreaseAllowance keyboard_arrow_up
Requirements help
Source Code
function decreaseAllowance(address spender, uint256 subtractedValue)
public
virtual
returns (bool)
{
_approve(
_msgSender(),
spender,
_allowances[_msgSender()][spender].sub(
subtractedValue,
"ERC20: decreased allowance below zero"
)
);
return true;
}
burn keyboard_arrow_up
burnFrom keyboard_arrow_up
Requirements help
Source Code
function burnFrom(address account, uint256 amount) public virtual {
uint256 decreasedAllowance = allowance(account, _msgSender()).sub(
amount,
"ERC20: burn amount exceeds allowance"
);
_approve(account, _msgSender(), decreasedAllowance);
_burn(account, amount);
}
frax_price keyboard_arrow_up
fxs_price keyboard_arrow_up
eth_usd_price keyboard_arrow_up
frax_info keyboard_arrow_up
Parameters help
This function has no parameters.
Source Code
function frax_info()
public
view
returns (
uint256,
uint256,
uint256,
uint256,
uint256,
uint256,
uint256,
uint256
)
{
return (
oracle_price(PriceChoice.FRAX), // frax_price()
oracle_price(PriceChoice.FXS), // fxs_price()
totalSupply(), // totalSupply()
global_collateral_ratio, // global_collateral_ratio()
globalCollateralValue(), // globalCollateralValue
minting_fee, // minting_fee()
redemption_fee, // redemption_fee()
uint256(eth_usd_pricer.getLatestPrice()).mul(PRICE_PRECISION).div(
uint256(10)**eth_usd_pricer_decimals
) //eth_usd_price
);
}
globalCollateralValue keyboard_arrow_up
Parameters help
This function has no parameters.
Source Code
function globalCollateralValue() public view returns (uint256) {
uint256 total_collateral_value_d18 = 0;
for (uint256 i = 0; i < frax_pools_array.length; i++) {
// Exclude null addresses
if (frax_pools_array[i] != address(0)) {
total_collateral_value_d18 = total_collateral_value_d18.add(
FraxPool(frax_pools_array[i]).collatDollarBalance()
);
}
}
return total_collateral_value_d18;
}
refreshCollateralRatio keyboard_arrow_up
Parameters help
This function has no parameters.
Requirements help
Source Code
function refreshCollateralRatio() public {
require(collateral_ratio_paused == false, "Collateral Ratio has been paused");
uint256 frax_price_cur = frax_price();
require(
block.timestamp - last_call_time >= refresh_cooldown,
"Must wait for the refresh cooldown since last refresh"
);
// Step increments are 0.25% (upon genesis, changable by setFraxStep())
if (frax_price_cur > price_target.add(price_band)) {
//decrease collateral ratio
if (global_collateral_ratio <= frax_step) {
//if within a step of 0, go to 0
global_collateral_ratio = 0;
} else {
global_collateral_ratio = global_collateral_ratio.sub(frax_step);
}
} else if (frax_price_cur < price_target.sub(price_band)) {
//increase collateral ratio
if (global_collateral_ratio.add(frax_step) >= 1000000) {
global_collateral_ratio = 1000000; // cap collateral ratio at 1.000000
} else {
global_collateral_ratio = global_collateral_ratio.add(frax_step);
}
}
last_call_time = block.timestamp; // Set the time of the last expansion
}
pool_burn_from keyboard_arrow_up
pool_mint keyboard_arrow_up
Modifiers help
onlyPools checks for the following:
Source Code
function pool_mint(address m_address, uint256 m_amount) public onlyPools {
super._mint(m_address, m_amount);
emit FRAXMinted(msg.sender, m_address, m_amount);
}
addPool keyboard_arrow_up
Modifiers help
onlyByOwnerOrGovernance checks for the following:
One or more of the following:
-
controller_address
must be equal to
the sender's address
- OR
timelock_address
must be equal to
the sender's address
- OR
owner_address
must be equal to
the sender's address
Requirements help
Source Code
function addPool(address pool_address) public onlyByOwnerOrGovernance {
require(frax_pools[pool_address] == false, "address already exists");
frax_pools[pool_address] = true;
frax_pools_array.push(pool_address);
}
removePool keyboard_arrow_up
Modifiers help
onlyByOwnerOrGovernance checks for the following:
One or more of the following:
-
controller_address
must be equal to
the sender's address
- OR
timelock_address
must be equal to
the sender's address
- OR
owner_address
must be equal to
the sender's address
Requirements help
Source Code
function removePool(address pool_address) public onlyByOwnerOrGovernance {
require(frax_pools[pool_address] == true, "address doesn't exist already");
// Delete from the mapping
delete frax_pools[pool_address];
// 'Delete' from the array by setting the address to 0x0
for (uint256 i = 0; i < frax_pools_array.length; i++) {
if (frax_pools_array[i] == pool_address) {
frax_pools_array[i] = address(0); // This will leave a null in the array and keep the indices the same
break;
}
}
}
setOwner keyboard_arrow_up
Modifiers help
onlyByOwnerOrGovernance checks for the following:
One or more of the following:
-
controller_address
must be equal to
the sender's address
- OR
timelock_address
must be equal to
the sender's address
- OR
owner_address
must be equal to
the sender's address
Source Code
function setOwner(address _owner_address) external onlyByOwnerOrGovernance {
owner_address = _owner_address;
}
setRedemptionFee keyboard_arrow_up
Modifiers help
onlyByOwnerOrGovernance checks for the following:
One or more of the following:
-
controller_address
must be equal to
the sender's address
- OR
timelock_address
must be equal to
the sender's address
- OR
owner_address
must be equal to
the sender's address
Source Code
function setRedemptionFee(uint256 red_fee) public onlyByOwnerOrGovernance {
redemption_fee = red_fee;
}
setMintingFee keyboard_arrow_up
Modifiers help
onlyByOwnerOrGovernance checks for the following:
One or more of the following:
-
controller_address
must be equal to
the sender's address
- OR
timelock_address
must be equal to
the sender's address
- OR
owner_address
must be equal to
the sender's address
Source Code
function setMintingFee(uint256 min_fee) public onlyByOwnerOrGovernance {
minting_fee = min_fee;
}
setFraxStep keyboard_arrow_up
Modifiers help
onlyByOwnerOrGovernance checks for the following:
One or more of the following:
-
controller_address
must be equal to
the sender's address
- OR
timelock_address
must be equal to
the sender's address
- OR
owner_address
must be equal to
the sender's address
Source Code
function setFraxStep(uint256 _new_step) public onlyByOwnerOrGovernance {
frax_step = _new_step;
}
setPriceTarget keyboard_arrow_up
Modifiers help
onlyByOwnerOrGovernance checks for the following:
One or more of the following:
-
controller_address
must be equal to
the sender's address
- OR
timelock_address
must be equal to
the sender's address
- OR
owner_address
must be equal to
the sender's address
Source Code
function setPriceTarget(uint256 _new_price_target)
public
onlyByOwnerOrGovernance
{
price_target = _new_price_target;
}
setRefreshCooldown keyboard_arrow_up
Modifiers help
onlyByOwnerOrGovernance checks for the following:
One or more of the following:
-
controller_address
must be equal to
the sender's address
- OR
timelock_address
must be equal to
the sender's address
- OR
owner_address
must be equal to
the sender's address
Source Code
function setRefreshCooldown(uint256 _new_cooldown)
public
onlyByOwnerOrGovernance
{
refresh_cooldown = _new_cooldown;
}
setFXSAddress keyboard_arrow_up
Modifiers help
onlyByOwnerOrGovernance checks for the following:
One or more of the following:
-
controller_address
must be equal to
the sender's address
- OR
timelock_address
must be equal to
the sender's address
- OR
owner_address
must be equal to
the sender's address
Source Code
function setFXSAddress(address _fxs_address) public onlyByOwnerOrGovernance {
fxs_address = _fxs_address;
}
setETHUSDOracle keyboard_arrow_up
Modifiers help
onlyByOwnerOrGovernance checks for the following:
One or more of the following:
-
controller_address
must be equal to
the sender's address
- OR
timelock_address
must be equal to
the sender's address
- OR
owner_address
must be equal to
the sender's address
Source Code
function setETHUSDOracle(address _eth_usd_consumer_address)
public
onlyByOwnerOrGovernance
{
eth_usd_consumer_address = _eth_usd_consumer_address;
eth_usd_pricer = ChainlinkETHUSDPriceConsumer(eth_usd_consumer_address);
eth_usd_pricer_decimals = eth_usd_pricer.getDecimals();
}
setTimelock keyboard_arrow_up
Modifiers help
onlyByOwnerOrGovernance checks for the following:
One or more of the following:
-
controller_address
must be equal to
the sender's address
- OR
timelock_address
must be equal to
the sender's address
- OR
owner_address
must be equal to
the sender's address
Source Code
function setTimelock(address new_timelock) external onlyByOwnerOrGovernance {
timelock_address = new_timelock;
}
setController keyboard_arrow_up
Modifiers help
onlyByOwnerOrGovernance checks for the following:
One or more of the following:
-
controller_address
must be equal to
the sender's address
- OR
timelock_address
must be equal to
the sender's address
- OR
owner_address
must be equal to
the sender's address
Source Code
function setController(address _controller_address)
external
onlyByOwnerOrGovernance
{
controller_address = _controller_address;
}
setPriceBand keyboard_arrow_up
Modifiers help
onlyByOwnerOrGovernance checks for the following:
One or more of the following:
-
controller_address
must be equal to
the sender's address
- OR
timelock_address
must be equal to
the sender's address
- OR
owner_address
must be equal to
the sender's address
Source Code
function setPriceBand(uint256 _price_band) external onlyByOwnerOrGovernance {
price_band = _price_band;
}
setFRAXEthOracle keyboard_arrow_up
Modifiers help
onlyByOwnerOrGovernance checks for the following:
One or more of the following:
-
controller_address
must be equal to
the sender's address
- OR
timelock_address
must be equal to
the sender's address
- OR
owner_address
must be equal to
the sender's address
Source Code
function setFRAXEthOracle(address _frax_oracle_addr, address _weth_address)
public
onlyByOwnerOrGovernance
{
frax_eth_oracle_address = _frax_oracle_addr;
fraxEthOracle = UniswapPairOracle(_frax_oracle_addr);
weth_address = _weth_address;
}
setFXSEthOracle keyboard_arrow_up
Modifiers help
onlyByOwnerOrGovernance checks for the following:
One or more of the following:
-
controller_address
must be equal to
the sender's address
- OR
timelock_address
must be equal to
the sender's address
- OR
owner_address
must be equal to
the sender's address
Source Code
function setFXSEthOracle(address _fxs_oracle_addr, address _weth_address)
public
onlyByOwnerOrGovernance
{
fxs_eth_oracle_address = _fxs_oracle_addr;
fxsEthOracle = UniswapPairOracle(_fxs_oracle_addr);
weth_address = _weth_address;
}
Internal Functions
Internal functions are parts of the contract that can't be used directly, but instead are used by the public functions listed above.
internal FRAXStablecoin.oracle_price keyboard_arrow_up
Source Code
function oracle_price(PriceChoice choice) internal view returns (uint256) {
// Get the ETH / USD price first, and cut it down to 1e6 precision
uint256 eth_usd_price = uint256(eth_usd_pricer.getLatestPrice())
.mul(PRICE_PRECISION)
.div(uint256(10)**eth_usd_pricer_decimals);
uint256 price_vs_eth;
if (choice == PriceChoice.FRAX) {
price_vs_eth = uint256(
fraxEthOracle.consult(weth_address, PRICE_PRECISION)
); // How much FRAX if you put in PRICE_PRECISION WETH
} else if (choice == PriceChoice.FXS) {
price_vs_eth = uint256(fxsEthOracle.consult(weth_address, PRICE_PRECISION)); // How much FXS if you put in PRICE_PRECISION WETH
} else revert("INVALID PRICE CHOICE. Needs to be either 0 (FRAX) or 1 (FXS)");
// Will be in 1e6 format
return eth_usd_price.mul(PRICE_PRECISION).div(price_vs_eth);
}
internal ERC20Custom._transfer keyboard_arrow_up
Requirements help
Source Code
function _transfer(
address sender,
address recipient,
uint256 amount
) internal virtual {
require(sender != address(0), "ERC20: transfer from the zero address");
require(recipient != address(0), "ERC20: transfer to the zero address");
_beforeTokenTransfer(sender, recipient, amount);
_balances[sender] = _balances[sender].sub(
amount,
"ERC20: transfer amount exceeds balance"
);
_balances[recipient] = _balances[recipient].add(amount);
emit Transfer(sender, recipient, amount);
}
internal ERC20Custom._mint keyboard_arrow_up
Source Code
function _mint(address account, uint256 amount) internal virtual {
require(account != address(0), "ERC20: mint to the zero address");
_beforeTokenTransfer(address(0), account, amount);
_totalSupply = _totalSupply.add(amount);
_balances[account] = _balances[account].add(amount);
emit Transfer(address(0), account, amount);
}
internal ERC20Custom._burn keyboard_arrow_up
Requirements help
Source Code
function _burn(address account, uint256 amount) internal virtual {
require(account != address(0), "ERC20: burn from the zero address");
_beforeTokenTransfer(account, address(0), amount);
_balances[account] = _balances[account].sub(
amount,
"ERC20: burn amount exceeds balance"
);
_totalSupply = _totalSupply.sub(amount);
emit Transfer(account, address(0), amount);
}
internal ERC20Custom._approve keyboard_arrow_up
Requirements help
Source Code
function _approve(
address owner,
address spender,
uint256 amount
) internal virtual {
require(owner != address(0), "ERC20: approve from the zero address");
require(spender != address(0), "ERC20: approve to the zero address");
_allowances[owner][spender] = amount;
emit Approval(owner, spender, amount);
}
internal ERC20Custom._burnFrom keyboard_arrow_up
Requirements help
Source Code
function _burnFrom(address account, uint256 amount) internal virtual {
_burn(account, amount);
_approve(
account,
_msgSender(),
_allowances[account][_msgSender()].sub(
amount,
"ERC20: burn amount exceeds allowance"
)
);
}
internal ERC20Custom._beforeTokenTransfer keyboard_arrow_up
internal Context.constructor keyboard_arrow_up
internal Context._msgSender keyboard_arrow_up
internal Context._msgData keyboard_arrow_up
Parameters help
This function has no parameters.
Source Code
function _msgData() internal view virtual returns (bytes memory) {
this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
return msg.data;
}
internal AccessControl._setupRole keyboard_arrow_up
internal AccessControl._setRoleAdmin keyboard_arrow_up
Source Code
function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {
emit RoleAdminChanged(role, _roles[role].adminRole, adminRole);
_roles[role].adminRole = adminRole;
}
internal AccessControl._grantRole keyboard_arrow_up
internal AccessControl._revokeRole keyboard_arrow_up
internal Context.constructor keyboard_arrow_up
internal Context._msgSender keyboard_arrow_up
internal Context._msgData keyboard_arrow_up
Parameters help
This function has no parameters.
Source Code
function _msgData() internal view virtual returns (bytes memory) {
this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
return msg.data;
}