Skip to content
Open
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ script = "src/script"
# A list of paths to look for libraries in
libs = ['lib', 'node_modules']
# Whether or not to enable `vm.ffi`
ffi = false
ffi = true
# Enables or disables the optimizer
optimizer = true
# The number of optimizer runs
Expand All @@ -29,6 +29,7 @@ bytecode_hash = "none"
cbor_metadata = false
# Contracts to track with --gas-report
#gas_reports = []
fs_permissions = [{ access = "read-write", path = "./"}]

[fuzz]
# Amount of runs per fuzz test
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
"@prb/math": "^4.1.0",
"ds-test": "github:dapphub/ds-test",
"forge-std": "github:foundry-rs/forge-std#60acb7aaadcce2d68e52986a0a66fe79f07d138f",
"frax-standard-solidity": "github:FraxFinance/frax-standard-solidity",
"frax-standard-solidity": "github:FraxFinance/frax-standard-solidity#v1.1.3",
"solidity-bytes-utils": "github:GNSPS/solidity-bytes-utils",
"solmate": "github:transmissions11/solmate#fadb2e2778adbf01c80275bfb99e5c14969d964b",
"@fraxfinance/layerzero-v2-upgradeable": "github:fraxfinance/LayerZero-v2-upgradeable#deps/pin-oz",
Expand Down
47 changes: 20 additions & 27 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 3 additions & 7 deletions src/contracts/ethereum/frxUSD/FrxUSD.sol
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,8 @@ pragma solidity ^0.8.0;
// Frax Finance: https://github.com/FraxFinance
// Tested for 18-decimal underlying assets only

import { FrxUSD2 } from "src/contracts/ethereum/frxUSD/versioning/FrxUSD2.sol";
import { FrxUSD3 } from "src/contracts/ethereum/frxUSD/versioning/FrxUSD3.sol";

contract FrxUSD is FrxUSD2 {
constructor(
address _ownerAddress,
string memory _name,
string memory _symbol
) FrxUSD2(_ownerAddress, _name, _symbol) {}
contract FrxUSD is FrxUSD3 {
constructor() FrxUSD3() {}
}
42 changes: 30 additions & 12 deletions src/contracts/ethereum/frxUSD/versioning/FrxUSD2.sol
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ contract FrxUSD2 is ERC20Permit, ERC20Burnable, Ownable2Step {
/// @notice Whether or not the contract is paused
bool public isPaused;

mapping(address => bool) public isFreezer;

uint256[45] private __gap;

/* ========== CONSTRUCTOR ========== */
/// @param _ownerAddress The initial owner
/// @param _name ERC20 name
Expand All @@ -37,16 +41,6 @@ contract FrxUSD2 is ERC20Permit, ERC20Burnable, Ownable2Step {
string memory _symbol
) ERC20(_name, _symbol) ERC20Permit(_name) Ownable(_ownerAddress) {}

/* ========== INITIALIZER ========== */
/// @dev Used to initialize the contract when it is behind a proxy
function initialize(address _owner, string memory _name, string memory _symbol) public {
require(owner() == address(0), "Already initialized");
if (_owner == address(0)) revert OwnerCannotInitToZeroAddress();
_transferOwnership(_owner);
StorageSlot.getBytesSlot(bytes32(uint256(3))).value = bytes(_name);
StorageSlot.getBytesSlot(bytes32(uint256(4))).value = bytes(_symbol);
}

/* ========== MODIFIERS ========== */

/// @notice A modifier that only allows a minters to call
Expand Down Expand Up @@ -106,6 +100,18 @@ contract FrxUSD2 is ERC20Permit, ERC20Burnable, Ownable2Step {
emit MinterRemoved(minter_address);
}

function addFreezer(address _freezer) external onlyOwner {
if (isFreezer[_freezer]) revert AlreadyFreezer();
isFreezer[_freezer] = true;
emit AddFreezer(_freezer);
}

function removeFreezer(address _freezer) external onlyOwner {
if (!isFreezer[_freezer]) revert NotFreezer();
isFreezer[_freezer] = false;
emit RemoveFreezer(_freezer);
}

/// @notice External admin gated function to unfreeze a set of accounts
/// @param _owners Array of accounts to be unfrozen
function thawMany(address[] memory _owners) external onlyOwner {
Expand All @@ -123,7 +129,8 @@ contract FrxUSD2 is ERC20Permit, ERC20Burnable, Ownable2Step {

/// @notice External admin gated function to batch freeze a set of accounts
/// @param _owners Array of accounts to be frozen
function freezeMany(address[] memory _owners) external onlyOwner {
function freezeMany(address[] memory _owners) external {
if (!isFreezer[msg.sender] && msg.sender != owner()) revert NotFreezer();
uint256 len = _owners.length;
for (uint256 i; i < len; ++i) {
_freeze(_owners[i]);
Expand All @@ -132,7 +139,8 @@ contract FrxUSD2 is ERC20Permit, ERC20Burnable, Ownable2Step {

/// @notice External admin gated function to freeze a given account
/// @param _owner The account to be
function freeze(address _owner) external onlyOwner {
function freeze(address _owner) external {
if (!isFreezer[msg.sender] && msg.sender != owner()) revert NotFreezer();
_freeze(_owner);
}

Expand Down Expand Up @@ -204,6 +212,14 @@ contract FrxUSD2 is ERC20Permit, ERC20Burnable, Ownable2Step {

/* ========== EVENTS ========== */

/// @notice Emitted when a freezer is added
/// @param freezer The address that was added as a freezer
event AddFreezer(address indexed freezer);

/// @notice Emitted when a freezer is removed
/// @param freezer The address that was removed as a freezer
event RemoveFreezer(address indexed freezer);

/// @notice Emitted whenever the bridge burns tokens from an account
/// @param account Address of the account tokens are being burned from
/// @param amount Amount of tokens burned
Expand Down Expand Up @@ -253,4 +269,6 @@ contract FrxUSD2 is ERC20Permit, ERC20Burnable, Ownable2Step {
error IsPaused();
error IsFrozen();
error OwnerCannotInitToZeroAddress();
error NotFreezer();
error AlreadyFreezer();
}
51 changes: 51 additions & 0 deletions src/contracts/ethereum/frxUSD/versioning/FrxUSD3.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
//SPDX-License-Identifier: Unlicense
pragma solidity ^0.8.0;

import { FrxUSD2, ERC20, EIP712, Nonces, ERC20Permit } from "src/contracts/ethereum/frxUSD/versioning/FrxUSD2.sol";
import { PermitModule } from "src/contracts/shared/core/modules/PermitModule.sol";
import { EIP3009Module, SignatureModule } from "src/contracts/shared/core/modules/EIP3009Module.sol";

/// @title FrxUSD v3.0.0
/// @notice Frax USD Stablecoin by Frax Finance
/// @dev v3.0.0 adds ERC-1271 and EIP-3009 support
contract FrxUSD3 is FrxUSD2, EIP3009Module, PermitModule {
constructor() FrxUSD2(address(1), "Frax USD", "frxUSD") {}

/*//////////////////////////////////////////////////////////////
Module Overrides
//////////////////////////////////////////////////////////////*/

function __transfer(address from, address to, uint256 amount) internal override returns (bool) {
ERC20._transfer(from, to, amount);
return true;
}

function __hashTypedDataV4(bytes32 structHash) internal view override(SignatureModule) returns (bytes32) {
return EIP712._hashTypedDataV4(structHash);
}

function __approve(address owner, address spender, uint256 amount) internal override(PermitModule) {
ERC20._approve(owner, spender, amount);
}

function __useNonce(address owner) internal override(PermitModule) returns (uint256) {
return Nonces._useNonce(owner);
}

function __domainSeparatorV4() internal view override(PermitModule) returns (bytes32) {
return EIP712._domainSeparatorV4();
}

function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) public override(ERC20Permit, PermitModule) {
return
PermitModule.permit({ owner: owner, spender: spender, value: value, deadline: deadline, v: v, r: r, s: s });
}
}
11 changes: 3 additions & 8 deletions src/contracts/ethereum/sfrxUSD/SfrxUSD.sol
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,8 @@ pragma solidity ^0.8.21;
// Frax Finance: https://github.com/FraxFinance
// Tested for 18-decimal underlying assets only

import { SfrxUSD2, IERC20 } from "src/contracts/ethereum/sfrxUSD/versioning/SfrxUSD2.sol";
import { SfrxUSD3 } from "src/contracts/ethereum/sfrxUSD/versioning/SfrxUSD3.sol";

contract SfrxUSD is SfrxUSD2 {
constructor(
IERC20 _underlying,
string memory _name,
string memory _symbol,
address _timelockAddress
) SfrxUSD2(_underlying, _name, _symbol, _timelockAddress) {}
contract SfrxUSD is SfrxUSD3 {
constructor(address _underlying) SfrxUSD3(_underlying) {}
}
2 changes: 2 additions & 0 deletions src/contracts/ethereum/sfrxUSD/versioning/SfrxUSD2.sol
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ contract SfrxUSD2 is LinearRewardsErc4626_2, Timelock2Step {
/// @dev Mapping is used for faster verification
mapping(address => bool) public minters;

uint256[47] public __gap;

function version() public pure virtual returns (string memory) {
return "2.0.0";
}
Expand Down
Loading