Skip to content
This repository was archived by the owner on Jul 19, 2026. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all 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
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ jobs:
- name: Install Foundry
uses: onbjerg/foundry-toolchain@v1
with:
version: nightly
version: stable

# - name: Check snapshot
# run: forge snapshot --check
Expand Down
14 changes: 14 additions & 0 deletions deployments/84532/matching.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"atomicSigningExecutor": "0xc65640E1f86caf0A22f7343F8667151c77E27EE4",
"auctionUtil": "0x754ac571828376FA1668b4842087D080243544a4",
"deposit": "0xD9490e907b9F2a1E1a9b33aaDB129Bf293790f8e",
"liquidate": "0xB2C763168498CDdF89AD7CC1663ACF7A99D4476A",
"matching": "0x1599636347FD5bA1fBE21D58AfE0b8B9cbe283FF",
"rfq": "0x4dCBaEe090D6E788422d9C2a3682BE8F9f070D3C",
"settlementUtil": "0xEDA153C08E30c5AD779cC7A3e437131dF12CC489",
"subAccountCreator": "0x9C6e4a0b33a3589b898b017015A55eb32eAF8bF9",
"trade": "0x0AAE65AaA66Fe7f54486cDbD007956d3De611990",
"transfer": "0xAF77Ced04c2590bd15e1822443BD753Eb4ff63B5",
"tsaShareHandler": "0x78f00622dd00774Fb9dec93D240FF1314C9B28aF",
"withdrawal": "0xfdDb0D00Df6d1569E46e72D35e7B6CEE4Bb7F9FB"
}
2 changes: 1 addition & 1 deletion foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ line_length = 120
tab_width = 2
bracket_spacing = false
int_types = 'short'
func_attrs_with_params_multiline = false
multiline_func_header = 'attributes_first'
quote_style = 'double'

# See more config options https://github.com/foundry-rs/foundry/tree/master/config
Expand Down
194 changes: 96 additions & 98 deletions src/fx/FXToken.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,105 +4,103 @@ import {AccessControlUpgradeable} from "openzeppelin-upgradeable/access/AccessCo
import {ERC20Upgradeable, Initializable} from "openzeppelin-upgradeable/token/ERC20/ERC20Upgradeable.sol";
import {SafeCast} from "openzeppelin/utils/math/SafeCast.sol";


contract FXToken is Initializable, ERC20Upgradeable, AccessControlUpgradeable {
using SafeCast for uint256;

bytes32 public constant MINTER_ROLE = keccak256("MINTER");
bytes32 public constant BLOCK_MANAGER_ROLE = keccak256("BLOCK_MANAGER");
// keccak256(abi.encode(uint256(keccak256("FxToken")) - 1)) & ~bytes32(uint256(0xff))
bytes32 private constant FxTokenStorageLocation = 0xfb8997de7bd810675586dece12917931ae29ba246c9d4d120b17fca6e2b68f00;


/// @custom:storage-location erc7201:FxToken
struct FxTokenStorage {
uint8 decimals;
mapping(address user => bool blocked) isBlocked;
}

function _getStorage() internal pure returns (FxTokenStorage storage s) {
bytes32 position = FxTokenStorageLocation;
assembly {
s.slot := position
}
}

///////////
// Setup //
///////////

constructor() {
_disableInitializers();
}

function initialize(string memory _name, string memory _symbol, uint _decimals) external initializer {
__ERC20_init_unchained(_name, _symbol);
_grantRole(DEFAULT_ADMIN_ROLE, msg.sender);

FxTokenStorage storage s = _getStorage();
s.decimals = _decimals.toUint8();
using SafeCast for uint;

bytes32 public constant MINTER_ROLE = keccak256("MINTER");
bytes32 public constant BLOCK_MANAGER_ROLE = keccak256("BLOCK_MANAGER");
// keccak256(abi.encode(uint256(keccak256("FxToken")) - 1)) & ~bytes32(uint256(0xff))
bytes32 private constant FxTokenStorageLocation = 0xfb8997de7bd810675586dece12917931ae29ba246c9d4d120b17fca6e2b68f00;

/// @custom:storage-location erc7201:FxToken
struct FxTokenStorage {
uint8 decimals;
mapping(address user => bool blocked) isBlocked;
}

function _getStorage() internal pure returns (FxTokenStorage storage s) {
bytes32 position = FxTokenStorageLocation;
assembly {
s.slot := position
}

////////////////
// Block List //
////////////////

function setBlocked(address user, bool blocked) public onlyRole(BLOCK_MANAGER_ROLE) {
require(user != address(0), "FxToken: cannot block zero address");
FxTokenStorage storage s = _getStorage();
s.isBlocked[user] = blocked;
emit Blocked(user, blocked);
}

function isBlocked(address user) public view returns (bool) {
return _getStorage().isBlocked[user];
}

///////////
// Setup //
///////////

constructor() {
_disableInitializers();
}

function initialize(string memory _name, string memory _symbol, uint _decimals) external initializer {
__ERC20_init_unchained(_name, _symbol);
_grantRole(DEFAULT_ADMIN_ROLE, msg.sender);

FxTokenStorage storage s = _getStorage();
s.decimals = _decimals.toUint8();
}

////////////////
// Block List //
////////////////

function setBlocked(address user, bool blocked) public onlyRole(BLOCK_MANAGER_ROLE) {
require(user != address(0), "FxToken: cannot block zero address");
FxTokenStorage storage s = _getStorage();
s.isBlocked[user] = blocked;
emit Blocked(user, blocked);
}

function isBlocked(address user) public view returns (bool) {
return _getStorage().isBlocked[user];
}

///////////////
// Mint/Burn //
///////////////

function mint(address to, uint amount) public onlyRole(MINTER_ROLE) {
FxTokenStorage storage s = _getStorage();
require(!s.isBlocked[msg.sender], "FxToken: minter is blocked");
_mint(to, amount);
}

function burn(address from, uint amount) public onlyRole(MINTER_ROLE) {
FxTokenStorage storage s = _getStorage();
require(!s.isBlocked[msg.sender], "FxToken: minter is blocked");

if (from == address(0)) {
revert ERC20InvalidSender(address(0));
}

///////////////
// Mint/Burn //
///////////////

function mint(address to, uint256 amount) public onlyRole(MINTER_ROLE) {
FxTokenStorage storage s = _getStorage();
require(!s.isBlocked[msg.sender], "FxToken: minter is blocked");
_mint(to, amount);
}

function burn(address from, uint256 amount) public onlyRole(MINTER_ROLE) {
FxTokenStorage storage s = _getStorage();
require(!s.isBlocked[msg.sender], "FxToken: minter is blocked");

if (from == address(0)) {
revert ERC20InvalidSender(address(0));
}
// Skip the _update call to avoid checking blocked status
super._update(from, address(0), amount);
}

/////////////////////
// ERC20 Overrides //
/////////////////////

function _update(address from, address to, uint256 value) internal override {
FxTokenStorage storage s = _getStorage();
require(!s.isBlocked[from], "FxToken: sender is blocked");
require(!s.isBlocked[to], "FxToken: recipient is blocked");
super._update(from, to, value);
}

function _spendAllowance(address owner, address spender, uint256 value) internal override {
FxTokenStorage storage s = _getStorage();
require(!s.isBlocked[spender], "FxToken: spender is blocked");
super._spendAllowance(owner, spender, value);
}

function decimals() public view virtual override returns (uint8) {
return _getStorage().decimals;
}

////////////
// Events //
////////////

event Blocked(address indexed user, bool blocked);
// Skip the _update call to avoid checking blocked status
super._update(from, address(0), amount);
}

/////////////////////
// ERC20 Overrides //
/////////////////////

function _update(address from, address to, uint value) internal override {
FxTokenStorage storage s = _getStorage();
require(!s.isBlocked[from], "FxToken: sender is blocked");
require(!s.isBlocked[to], "FxToken: recipient is blocked");
super._update(from, to, value);
}

function _spendAllowance(address owner, address spender, uint value) internal override {
FxTokenStorage storage s = _getStorage();
require(!s.isBlocked[spender], "FxToken: spender is blocked");
super._spendAllowance(owner, spender, value);
}

function decimals() public view virtual override returns (uint8) {
return _getStorage().decimals;
}

////////////
// Events //
////////////

event Blocked(address indexed user, bool blocked);
}
7 changes: 2 additions & 5 deletions src/modules/RfqModule.sol
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ contract RfqModule is IRfqModule, BaseModule {
cashTransfer = perpDelta.multiplyDecimal(tradeData.amount);
} else if (isDatedFutureAsset[tradeData.asset]) {
cashTransfer = 0;
assetData = bytes32(uint256(tradeData.price));
assetData = bytes32(uint(tradeData.price));
} else {
cashTransfer = tradeData.price.toInt256().multiplyDecimal(tradeData.amount);
}
Expand All @@ -146,10 +146,7 @@ contract RfqModule is IRfqModule, BaseModule {
});

matchedOrders[i] = IRfqModule.MatchedOrderData({
asset: tradeData.asset,
subId: tradeData.subId,
quoteAmt: cashTransfer,
baseAmt: tradeData.amount
asset: tradeData.asset, subId: tradeData.subId, quoteAmt: cashTransfer, baseAmt: tradeData.amount
});
}

Expand Down
2 changes: 1 addition & 1 deletion src/modules/TradeModule.sol
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ contract TradeModule is ITradeModule, BaseModule {
amtQuote = perpDelta.multiplyDecimal(int(fillDetails.amountFilled));
} else if (isDatedFutureAsset[matchedOrder.data.asset]) {
amtQuote = 0;
assetData = bytes32(uint256(fillDetails.price));
assetData = bytes32(uint(fillDetails.price));
} else {
amtQuote = fillDetails.price.multiplyDecimal(int(fillDetails.amountFilled));
}
Expand Down
7 changes: 1 addition & 6 deletions src/periphery/LyraAuctionUtils.sol
Original file line number Diff line number Diff line change
Expand Up @@ -121,12 +121,7 @@ contract LyraAuctionUtils {

function _transferCash(uint fromId, uint toId, uint amount, bytes memory managerData) internal {
ISubAccounts.AssetTransfer memory adjustment = ISubAccounts.AssetTransfer({
fromAcc: fromId,
toAcc: toId,
asset: IAsset(cash),
subId: 0,
amount: amount.toInt256(),
assetData: bytes32(0)
fromAcc: fromId, toAcc: toId, asset: IAsset(cash), subId: 0, amount: amount.toInt256(), assetData: bytes32(0)
});
subAccounts.submitTransfer(adjustment, managerData);
}
Expand Down
10 changes: 9 additions & 1 deletion src/tokenizedSubaccounts/BaseOnChainSigningTSA.sol
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,15 @@ abstract contract BaseOnChainSigningTSA is BaseTSA {
return bytes4(0);
}

function _isValidSignature(bytes32 _hash, bytes memory /* _signature */ ) internal view virtual returns (bool) {
function _isValidSignature(
bytes32 _hash,
bytes memory /* _signature */
)
internal
view
virtual
returns (bool)
{
BaseSigningTSAStorage storage $ = _getBaseSigningTSAStorage();

return !$.signaturesDisabled && $.signedData[_hash];
Expand Down
10 changes: 6 additions & 4 deletions src/tokenizedSubaccounts/CCTSA.sol
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,7 @@ import {IWithdrawalModule} from "../interfaces/IWithdrawalModule.sol";
import {ITradeModule} from "../interfaces/ITradeModule.sol";
import {IMatching} from "../interfaces/IMatching.sol";

import {
StandardManager, IStandardManager, IVolFeed, IForwardFeed
} from "v2-core/src/risk-managers/StandardManager.sol";
import {StandardManager, IStandardManager, IVolFeed, IForwardFeed} from "v2-core/src/risk-managers/StandardManager.sol";
import "./CollateralManagementTSA.sol";

/// @title CoveredCallTSA
Expand Down Expand Up @@ -147,7 +145,11 @@ contract CoveredCallTSA is CollateralManagementTSA {
///////////////////////
// Action Validation //
///////////////////////
function _verifyAction(IMatching.Action memory action, bytes32 actionHash, bytes memory /* extraData */ )
function _verifyAction(
IMatching.Action memory action,
bytes32 actionHash,
bytes memory /* extraData */
)
internal
virtual
override
Expand Down
24 changes: 16 additions & 8 deletions src/tokenizedSubaccounts/LevBasisTSA.sol
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,7 @@ import {IWithdrawalModule} from "../interfaces/IWithdrawalModule.sol";
import {IMatching} from "../interfaces/IMatching.sol";
import {IWrappedERC20Asset} from "v2-core/src/interfaces/IWrappedERC20Asset.sol";

import {
StandardManager, IStandardManager, IVolFeed, IForwardFeed
} from "v2-core/src/risk-managers/StandardManager.sol";
import {StandardManager, IStandardManager, IVolFeed, IForwardFeed} from "v2-core/src/risk-managers/StandardManager.sol";
import {ITradeModule} from "../interfaces/ITradeModule.sol";
import {CollateralManagementTSA} from "./CollateralManagementTSA.sol";

Expand Down Expand Up @@ -191,7 +189,11 @@ contract LeveragedBasisTSA is CollateralManagementTSA {
///////////////////////
// Action Validation //
///////////////////////
function _verifyAction(IMatching.Action memory action, bytes32 actionHash, bytes memory /*extraData*/ )
function _verifyAction(
IMatching.Action memory action,
bytes32 actionHash,
bytes memory /*extraData*/
)
internal
virtual
override
Expand Down Expand Up @@ -325,8 +327,9 @@ contract LeveragedBasisTSA is CollateralManagementTSA {
}
LBTSAStorage storage $ = _getLBTSAStorage();

uint newUnderlyingBase =
isWithdrawal ? (tradeHelperVars.underlyingBase.toInt256() + amtDelta).toUint256() : tradeHelperVars.underlyingBase;
uint newUnderlyingBase = isWithdrawal
? (tradeHelperVars.underlyingBase.toInt256() + amtDelta).toUint256()
: tradeHelperVars.underlyingBase;

// Leverage
uint leverage = tradeHelperVars.baseBalance.divideDecimal(tradeHelperVars.underlyingBase);
Expand All @@ -339,7 +342,10 @@ contract LeveragedBasisTSA is CollateralManagementTSA {

require(
_isWithinBounds(
leverage.toInt256(), newLeverage.toInt256(), $.lbParams.leverageFloor.toInt256(), $.lbParams.leverageCeil.toInt256()
leverage.toInt256(),
newLeverage.toInt256(),
$.lbParams.leverageFloor.toInt256(),
$.lbParams.leverageCeil.toInt256()
),
LBT_PostTradeLeverageOutOfRange()
);
Expand All @@ -363,7 +369,9 @@ contract LeveragedBasisTSA is CollateralManagementTSA {
return false;
}

function _verifyEmaMarkLoss(ITradeModule.TradeData memory tradeData, TradeHelperVars memory tradeHelperVars) internal {
function _verifyEmaMarkLoss(ITradeModule.TradeData memory tradeData, TradeHelperVars memory tradeHelperVars)
internal
{
LBTSAStorage storage $ = _getLBTSAStorage();

int priceToCheck = (tradeHelperVars.isBaseTrade ? tradeHelperVars.basePrice : tradeHelperVars.perpPrice).toInt256();
Expand Down
4 changes: 1 addition & 3 deletions src/tokenizedSubaccounts/PPTSA.sol
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,7 @@ import {IWithdrawalModule} from "../interfaces/IWithdrawalModule.sol";
import {IMatching} from "../interfaces/IMatching.sol";
import {IRfqModule} from "../interfaces/IRfqModule.sol";

import {
StandardManager, IStandardManager, IVolFeed, IForwardFeed
} from "v2-core/src/risk-managers/StandardManager.sol";
import {StandardManager, IStandardManager, IVolFeed, IForwardFeed} from "v2-core/src/risk-managers/StandardManager.sol";
import {ITradeModule} from "../interfaces/ITradeModule.sol";
import {CollateralManagementTSA} from "./CollateralManagementTSA.sol";

Expand Down
Loading
Loading