Skip to content

Commit

Permalink
Chore/organize functions (#31)
Browse files Browse the repository at this point in the history
* moving functions around

* fmt and snapshot

* adding fundadmin check in _assertCallerHasAccess

* fmt and snapshot

* setting core libs to master

* fmt and snapshot
  • Loading branch information
dsshap authored Apr 2, 2024
1 parent b740a27 commit a24695e
Show file tree
Hide file tree
Showing 13 changed files with 803 additions and 716 deletions.
1,034 changes: 518 additions & 516 deletions .gas-snapshot

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion lib/core-physical
4 changes: 3 additions & 1 deletion script/deploy-launch-cash.sol
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,9 @@ contract Deploy is Script, Utilities {
function deployCrossMarginEngine(address grappa, address optionToken) public returns (address crossMarginEngine) {
// ============ Deploy Cross Margin Engine (Upgradable) ============== //
address engineImplementation = address(
new CrossMarginCashEngine(address(grappa), optionToken, vm.envAddress("CrossMarginCashOracle"), vm.envAddress("RolesAuthorityProxy"))
new CrossMarginCashEngine(
address(grappa), optionToken, vm.envAddress("CrossMarginCashOracle"), vm.envAddress("RolesAuthorityProxy")
)
);
bytes memory engineData =
abi.encodeWithSelector(CrossMarginCashEngine.initialize.selector, vm.envAddress("CrossMarginOwner"));
Expand Down
4 changes: 3 additions & 1 deletion script/deploy-upgrade-cash.sol
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@ contract Deploy is Script {
function deployCrossMarginEngine(address grappa, address optionToken) public {
// ============ Deploy Cross Margin Engine (Upgradable) ============== //
address engineImplementation = address(
new CrossMarginCashEngine(address(grappa), optionToken, vm.envAddress("CrossMarginCashOracle"), vm.envAddress("RolesAuthorityProxy"))
new CrossMarginCashEngine(
address(grappa), optionToken, vm.envAddress("CrossMarginCashOracle"), vm.envAddress("RolesAuthorityProxy")
)
);

console.log("CrossMargin Cash Engine: \t\t\t", engineImplementation);
Expand Down
4 changes: 3 additions & 1 deletion script/deploy-upgrade-physical.sol
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ contract DeployPhysicalMarginEngine is Script {

// ============ Deploy Cross Margin Engine (Upgradable) ============== //
address engineImplementation = address(
new CrossMarginPhysicalEngine(vm.envAddress("PomaceProxy"), vm.envAddress("PomaceOptionToken"), vm.envAddress("RolesAuthorityProxy"))
new CrossMarginPhysicalEngine(
vm.envAddress("PomaceProxy"), vm.envAddress("PomaceOptionToken"), vm.envAddress("RolesAuthorityProxy")
)
);

console.log("CrossMargin Physical Engine: \t\t", engineImplementation);
Expand Down
239 changes: 127 additions & 112 deletions src/settled-cash/CrossMarginCashEngine.sol
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ contract CrossMarginCashEngine is
/// this give every account access to 256 sub-accounts
mapping(address => CrossMarginAccount) internal accounts;

///@dev contract that verifies permissions
///@dev ***DEPRECATED*** contract that verifies permissions
/// if not set allows anyone to transact
/// checks msg.sender on execute & batchExecute
/// checks recipient on payCashValue
Expand Down Expand Up @@ -148,51 +148,60 @@ contract CrossMarginCashEngine is
}

/*///////////////////////////////////////////////////////////////
Override Upgrade Permission
Execute and BatchExecute
//////////////////////////////////////////////////////////////*/

/**
* @dev Upgradable by the owner.
*
* @notice gets access status of an address
* @dev if whitelist address is not set, it ignores this
* @param _address address
*/
function _authorizeUpgrade(address /*newImplementation*/ ) internal view override {
_checkOwner();
function _checkPermissioned(address _address) internal view {
if (!authority.canCall(_address, address(this), msg.sig)) revert NoAccess();
}

/*///////////////////////////////////////////////////////////////
External Functions
//////////////////////////////////////////////////////////////*/

/**
* @notice sets the Collateralizable Mask for a pair of assets
* @param _asset0 the address of the asset 0
* @param _asset1 the address of the asset 1
* @param _value is margin-able
* @notice execute multiple actions on one subAccounts
* @dev also check access of msg.sender
*/
function setCollateralizable(address _asset0, address _asset1, bool _value) external {
_checkOwner();

uint256 collateralId = grappa.assetIds(_asset0);
uint256 mask = 1 << grappa.assetIds(_asset1);

if (_value) collateralizable[collateralId] |= mask;
else collateralizable[collateralId] &= ~mask;

emit CollateralizableSet(_asset0, _asset1, _value);
}
function _execute(address _subAccount, ActionArgs[] calldata actions) internal {
_assertCallerHasAccess(_subAccount);

/**
* @dev check if a pair of assets are collateralizable
*/
function isCollateralizable(address _asset0, address _asset1) external view returns (bool) {
return _isCollateralizable(grappa.assetIds(_asset0), grappa.assetIds(_asset1));
}
// update the account storage and do external calls on the flight
for (uint256 i; i < actions.length;) {
if (actions[i].action == ActionType.AddCollateral) {
_addCollateral(_subAccount, actions[i].data);
} else if (actions[i].action == ActionType.RemoveCollateral) {
_removeCollateral(_subAccount, actions[i].data);
} else if (actions[i].action == ActionType.MintShort) {
_mintOption(_subAccount, actions[i].data);
} else if (actions[i].action == ActionType.MintShortIntoAccount) {
_mintOptionIntoAccount(_subAccount, actions[i].data);
} else if (actions[i].action == ActionType.BurnShort) {
_burnOption(_subAccount, actions[i].data);
} else if (actions[i].action == ActionType.BurnShortInAccount) {
_burnOptionFromAccount(_subAccount, actions[i].data);
} else if (actions[i].action == ActionType.TransferLong) {
_transferLong(_subAccount, actions[i].data);
} else if (actions[i].action == ActionType.TransferShort) {
_transferShort(_subAccount, actions[i].data);
} else if (actions[i].action == ActionType.TransferCollateral) {
_transferCollateral(_subAccount, actions[i].data);
} else if (actions[i].action == ActionType.AddLong) {
_addOption(_subAccount, actions[i].data);
} else if (actions[i].action == ActionType.RemoveLong) {
_removeOption(_subAccount, actions[i].data);
} else if (actions[i].action == ActionType.SettleAccount) {
_settle(_subAccount);
} else {
revert CM_UnsupportedAction();
}

/**
* @dev check if a pair of assets are collateralizable
*/
function isCollateralizable(uint8 _asset0, uint8 _asset1) external view returns (bool) {
return _isCollateralizable(_asset0, _asset1);
// increase i without checking overflow
unchecked {
++i;
}
}
}

/**
Expand Down Expand Up @@ -262,21 +271,6 @@ contract CrossMarginCashEngine is
return _getMinCollateral(account);
}

/**
* @notice move an account to someone else
* @dev expected to be call by account owner
* @param _subAccount the id of subaccount to transfer
* @param _newSubAccount the id of receiving account
*/
function transferAccount(address _subAccount, address _newSubAccount) external {
if (!_isPrimaryAccountFor(msg.sender, _subAccount)) revert NoAccess();

if (!accounts[_newSubAccount].isEmpty()) revert CM_AccountIsNotEmpty();
accounts[_newSubAccount] = accounts[_subAccount];

delete accounts[_subAccount];
}

/**
* @dev view function to get all shorts, longs and collaterals
*/
Expand Down Expand Up @@ -411,7 +405,6 @@ contract CrossMarginCashEngine is
* Override Sate changing functions *
* ========================================================= *
*/

function _addCollateralToAccount(address _subAccount, uint8 collateralId, uint80 amount) internal override {
accounts[_subAccount].addCollateral(collateralId, amount);
}
Expand Down Expand Up @@ -563,74 +556,19 @@ contract CrossMarginCashEngine is
* ========================================================= *
*/

/**
* @notice gets access status of an address
* @dev if whitelist address is not set, it ignores this
* @param _address address
*/
function _checkPermissioned(address _address) internal view {
if (!authority.canCall(_address, address(this), msg.sig)) revert NoAccess();
}

/**
* @notice execute multiple actions on one subAccounts
* @dev also check access of msg.sender
*/
function _execute(address _subAccount, ActionArgs[] calldata actions) internal {
_assertCallerHasAccess(_subAccount);

// update the account storage and do external calls on the flight
for (uint256 i; i < actions.length;) {
if (actions[i].action == ActionType.AddCollateral) {
_addCollateral(_subAccount, actions[i].data);
} else if (actions[i].action == ActionType.RemoveCollateral) {
_removeCollateral(_subAccount, actions[i].data);
} else if (actions[i].action == ActionType.MintShort) {
_mintOption(_subAccount, actions[i].data);
} else if (actions[i].action == ActionType.MintShortIntoAccount) {
_mintOptionIntoAccount(_subAccount, actions[i].data);
} else if (actions[i].action == ActionType.BurnShort) {
_burnOption(_subAccount, actions[i].data);
} else if (actions[i].action == ActionType.BurnShortInAccount) {
_burnOptionFromAccount(_subAccount, actions[i].data);
} else if (actions[i].action == ActionType.TransferLong) {
_transferLong(_subAccount, actions[i].data);
} else if (actions[i].action == ActionType.TransferShort) {
_transferShort(_subAccount, actions[i].data);
} else if (actions[i].action == ActionType.TransferCollateral) {
_transferCollateral(_subAccount, actions[i].data);
} else if (actions[i].action == ActionType.AddLong) {
_addOption(_subAccount, actions[i].data);
} else if (actions[i].action == ActionType.RemoveLong) {
_removeOption(_subAccount, actions[i].data);
} else if (actions[i].action == ActionType.SettleAccount) {
_settle(_subAccount);
} else {
revert CM_UnsupportedAction();
}

// increase i without checking overflow
unchecked {
++i;
}
}
}

/**
* @dev get minimum collateral requirement for an account
*/
function _getMinCollateral(CrossMarginAccount memory account) internal view returns (Balance[] memory) {
return CrossMarginCashMath.getMinCollateralForPositions(grappa, account.shorts, account.longs);
}

/**
* @dev check if a pair of assetIds are collateralizable
*/
function _isCollateralizable(uint8 _assetId0, uint8 _assetId1) internal view returns (bool) {
if (_assetId0 == _assetId1) return true;
function _assertCallerHasAccess(address _subAccount) internal override {
if (_isPrimaryAccountFor(msg.sender, _subAccount)) return;

uint256 mask = 1 << _assetId1;
return collateralizable[_assetId0] & mask != 0;
if (!authority.doesUserHaveRole(tx.origin, Role.System_FundAdmin)) {
super._assertCallerHasAccess(_subAccount);
}
}

function _computeDomainSeparator() internal view returns (bytes32) {
Expand All @@ -644,4 +582,81 @@ contract CrossMarginCashEngine is
)
);
}

/*///////////////////////////////////////////////////////////////
Collateralizable Functions
//////////////////////////////////////////////////////////////*/

/**
* @dev check if a pair of assetIds are collateralizable
*/
function _isCollateralizable(uint8 _assetId0, uint8 _assetId1) internal view returns (bool) {
if (_assetId0 == _assetId1) return true;

uint256 mask = 1 << _assetId1;
return collateralizable[_assetId0] & mask != 0;
}

/**
* @notice sets the Collateralizable Mask for a pair of assets
* @param _asset0 the address of the asset 0
* @param _asset1 the address of the asset 1
* @param _value is margin-able
*/
function setCollateralizable(address _asset0, address _asset1, bool _value) external {
_checkOwner();

uint256 collateralId = grappa.assetIds(_asset0);
uint256 mask = 1 << grappa.assetIds(_asset1);

if (_value) collateralizable[collateralId] |= mask;
else collateralizable[collateralId] &= ~mask;

emit CollateralizableSet(_asset0, _asset1, _value);
}

/**
* @dev check if a pair of assets are collateralizable
*/
function isCollateralizable(address _asset0, address _asset1) external view returns (bool) {
return _isCollateralizable(grappa.assetIds(_asset0), grappa.assetIds(_asset1));
}

/**
* @dev check if a pair of assets are collateralizable
*/
function isCollateralizable(uint8 _asset0, uint8 _asset1) external view returns (bool) {
return _isCollateralizable(_asset0, _asset1);
}

/*///////////////////////////////////////////////////////////////
Transfer Account Functions
//////////////////////////////////////////////////////////////*/

/**
* @notice move an account to someone else
* @dev expected to be call by account owner
* @param _subAccount the id of subaccount to transfer
* @param _newSubAccount the id of receiving account
*/
function transferAccount(address _subAccount, address _newSubAccount) external {
if (!_isPrimaryAccountFor(msg.sender, _subAccount)) revert NoAccess();

if (!accounts[_newSubAccount].isEmpty()) revert CM_AccountIsNotEmpty();
accounts[_newSubAccount] = accounts[_subAccount];

delete accounts[_subAccount];
}

/*///////////////////////////////////////////////////////////////
Override Upgrade Permission
//////////////////////////////////////////////////////////////*/

/**
* @dev Upgradable by the owner.
*
*/
function _authorizeUpgrade(address /*newImplementation*/ ) internal view override {
_checkOwner();
}
}
Loading

0 comments on commit a24695e

Please sign in to comment.