Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reduce Controller bytecode size #433

Merged
merged 28 commits into from
Jun 24, 2021
Merged
Show file tree
Hide file tree
Changes from 26 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
aab256e
feat: getVaultWithDetails()
haythemsellami Jun 23, 2021
3823d5e
remove leading 0s
aleone Jun 23, 2021
2847b41
adjust return in hasExpired
aleone Jun 23, 2021
eebe22d
adjust return in getPayout
aleone Jun 23, 2021
bf75133
adjust private interfaces
aleone Jun 24, 2021
6e868e9
remove duplicate partial and full pauser addresses
aleone Jun 24, 2021
d791f4d
interfaces back to public, marginVault error codes
aleone Jun 24, 2021
19b295a
action error strings
antoncoding Jun 24, 2021
69cef9d
try catch
antoncoding Jun 24, 2021
e4b3dae
avoid changing slot
antoncoding Jun 24, 2021
cc3abe0
test: fix pauser tests
antoncoding Jun 24, 2021
92afe2d
overload isSettlementAllowed
antoncoding Jun 24, 2021
9b9068d
add getOTokenDetails in calculator
antoncoding Jun 24, 2021
5b00abf
refactor isSettlementAllowed
antoncoding Jun 24, 2021
22190b2
fix action tests
antoncoding Jun 24, 2021
39728d1
fix controller tests
antoncoding Jun 24, 2021
f8fbbac
fix: setPauser
antoncoding Jun 24, 2021
d0df66b
fix: MarginVault error code
antoncoding Jun 24, 2021
a4b8fda
fix: integration test error codes
antoncoding Jun 24, 2021
1445444
revert partial and full pauser change
antoncoding Jun 24, 2021
dd801e8
test: fix
haythemsellami Jun 24, 2021
3baa668
change functions visibility and update order
haythemsellami Jun 24, 2021
c35e426
test: use getVault() in controller.test.ts
haythemsellami Jun 24, 2021
a6df7d3
fix: backward compatibility for redeeming
haythemsellami Jun 24, 2021
a524b27
test: backward compatibility'
haythemsellami Jun 24, 2021
1093771
chore: rename _getOTokenDetail()
haythemsellami Jun 24, 2021
c50f03a
docs: update docs & diagrams
CruzMolina Jun 24, 2021
30a576f
fix: typo
haythemsellami Jun 24, 2021
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
302 changes: 179 additions & 123 deletions contracts/core/Controller.sol

Large diffs are not rendered by default.

46 changes: 41 additions & 5 deletions contracts/core/MarginCalculator.sol
Original file line number Diff line number Diff line change
Expand Up @@ -364,16 +364,14 @@ contract MarginCalculator is Ownable {
function getExpiredPayoutRate(address _otoken) external view returns (uint256) {
require(_otoken != address(0), "MarginCalculator: Invalid token address");

OtokenInterface otoken = OtokenInterface(_otoken);

(
address collateral,
address underlying,
address strikeAsset,
uint256 strikePrice,
uint256 expiry,
bool isPut
) = otoken.getOtokenDetails();
) = _getOtokenDetails(_otoken);

require(now >= expiry, "MarginCalculator: Otoken not expired yet");

Expand Down Expand Up @@ -1072,7 +1070,7 @@ contract MarginCalculator is Ownable {
vaultDetails.longStrikePrice,
vaultDetails.longExpiryTimestamp,
vaultDetails.isLongPut
) = long.getOtokenDetails();
) = _getOtokenDetails(address(long));
vaultDetails.longCollateralDecimals = uint256(ERC20Interface(vaultDetails.longCollateralAsset).decimals());
}

Expand All @@ -1086,7 +1084,7 @@ contract MarginCalculator is Ownable {
vaultDetails.shortStrikePrice,
vaultDetails.shortExpiryTimestamp,
vaultDetails.isShortPut
) = short.getOtokenDetails();
) = _getOtokenDetails(address(short));
vaultDetails.shortCollateralDecimals = uint256(
ERC20Interface(vaultDetails.shortCollateralAsset).decimals()
);
Expand Down Expand Up @@ -1249,4 +1247,42 @@ contract MarginCalculator is Ownable {

return _underlyingPrice.isGreaterThan(_strikePrice) ? _underlyingPrice.sub(_strikePrice) : ZERO;
}

/**
* @dev get otoken detail, from both otoken versions
*/
function _getOtokenDetails(address _otoken)
internal
view
returns (
address,
address,
address,
uint256,
uint256,
bool
)
{
OtokenInterface otoken = OtokenInterface(_otoken);
try otoken.getOtokenDetails() returns (
address collateral,
address underlying,
address strike,
uint256 strikePrice,
uint256 expiry,
bool isPut
) {
return (collateral, underlying, strike, strikePrice, expiry, isPut);
} catch {
// v1 otoken
return (
otoken.collateralAsset(),
otoken.underlyingAsset(),
otoken.strikeAsset(),
otoken.strikePrice(),
otoken.expiryTimestamp(),
otoken.isPut()
);
}
}
}
73 changes: 47 additions & 26 deletions contracts/libs/Actions.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,30 @@ import {MarginVault} from "./MarginVault.sol";
* @title Actions
* @author Opyn Team
* @notice A library that provides a ActionArgs struct, sub types of Action structs, and functions to parse ActionArgs into specific Actions.
* errorCode
* A1 can only parse arguments for open vault actions
* A2 cannot open vault for an invalid account
* A3 cannot open vault with an invalid type
* A4 can only parse arguments for mint actions
* A5 cannot mint from an invalid account
* A6 can only parse arguments for burn actions
* A7 cannot burn from an invalid account
* A8 can only parse arguments for deposit actions
* A9 cannot deposit to an invalid account
* A10 can only parse arguments for withdraw actions
* A11 cannot withdraw from an invalid account
* A12 cannot withdraw to an invalid account
* A13 can only parse arguments for redeem actions
* A14 cannot redeem to an invalid account
* A15 can only parse arguments for settle vault actions
* A16 cannot settle vault for an invalid account
* A17 cannot withdraw payout to an invalid account
* A18 can only parse arguments for liquidate action
* A19 cannot liquidate vault for an invalid account owner
* A20 cannot send collateral to an invalid account
* A21 cannot parse liquidate action with no round id
* A22 can only parse arguments for call actions
* A23 target address cannot be address(0)
*/
library Actions {
// possible actions that can be performed
Expand Down Expand Up @@ -163,8 +187,8 @@ library Actions {
* @return arguments for a open vault action
*/
function _parseOpenVaultArgs(ActionArgs memory _args) internal pure returns (OpenVaultArgs memory) {
require(_args.actionType == ActionType.OpenVault, "Actions: can only parse arguments for open vault actions");
require(_args.owner != address(0), "Actions: cannot open vault for an invalid account");
require(_args.actionType == ActionType.OpenVault, "A1");
require(_args.owner != address(0), "A2");

// if not _args.data included, vault type will be 0 by default
uint256 vaultType;
Expand All @@ -175,7 +199,7 @@ library Actions {
}

// for now we only have 2 vault types
require(vaultType < 2, "Actions: cannot open vault with an invalid type");
require(vaultType < 2, "A3");

return OpenVaultArgs({owner: _args.owner, vaultId: _args.vaultId, vaultType: vaultType});
}
Expand All @@ -186,8 +210,8 @@ library Actions {
* @return arguments for a mint action
*/
function _parseMintArgs(ActionArgs memory _args) internal pure returns (MintArgs memory) {
require(_args.actionType == ActionType.MintShortOption, "Actions: can only parse arguments for mint actions");
require(_args.owner != address(0), "Actions: cannot mint from an invalid account");
require(_args.actionType == ActionType.MintShortOption, "A4");
require(_args.owner != address(0), "A5");

return
MintArgs({
Expand All @@ -206,8 +230,8 @@ library Actions {
* @return arguments for a burn action
*/
function _parseBurnArgs(ActionArgs memory _args) internal pure returns (BurnArgs memory) {
require(_args.actionType == ActionType.BurnShortOption, "Actions: can only parse arguments for burn actions");
require(_args.owner != address(0), "Actions: cannot burn from an invalid account");
require(_args.actionType == ActionType.BurnShortOption, "A6");
require(_args.owner != address(0), "A7");

return
BurnArgs({
Expand All @@ -228,9 +252,9 @@ library Actions {
function _parseDepositArgs(ActionArgs memory _args) internal pure returns (DepositArgs memory) {
require(
(_args.actionType == ActionType.DepositLongOption) || (_args.actionType == ActionType.DepositCollateral),
"Actions: can only parse arguments for deposit actions"
"A8"
);
require(_args.owner != address(0), "Actions: cannot deposit to an invalid account");
require(_args.owner != address(0), "A9");

return
DepositArgs({
Expand All @@ -251,10 +275,10 @@ library Actions {
function _parseWithdrawArgs(ActionArgs memory _args) internal pure returns (WithdrawArgs memory) {
require(
(_args.actionType == ActionType.WithdrawLongOption) || (_args.actionType == ActionType.WithdrawCollateral),
"Actions: can only parse arguments for withdraw actions"
"A10"
);
require(_args.owner != address(0), "Actions: cannot withdraw from an invalid account");
require(_args.secondAddress != address(0), "Actions: cannot withdraw to an invalid account");
require(_args.owner != address(0), "A11");
require(_args.secondAddress != address(0), "A12");

return
WithdrawArgs({
Expand All @@ -273,8 +297,8 @@ library Actions {
* @return arguments for a redeem action
*/
function _parseRedeemArgs(ActionArgs memory _args) internal pure returns (RedeemArgs memory) {
require(_args.actionType == ActionType.Redeem, "Actions: can only parse arguments for redeem actions");
require(_args.secondAddress != address(0), "Actions: cannot redeem to an invalid account");
require(_args.actionType == ActionType.Redeem, "A13");
require(_args.secondAddress != address(0), "A14");

return RedeemArgs({receiver: _args.secondAddress, otoken: _args.asset, amount: _args.amount});
}
Expand All @@ -285,21 +309,18 @@ library Actions {
* @return arguments for a settle vault action
*/
function _parseSettleVaultArgs(ActionArgs memory _args) internal pure returns (SettleVaultArgs memory) {
require(
_args.actionType == ActionType.SettleVault,
"Actions: can only parse arguments for settle vault actions"
);
require(_args.owner != address(0), "Actions: cannot settle vault for an invalid account");
require(_args.secondAddress != address(0), "Actions: cannot withdraw payout to an invalid account");
require(_args.actionType == ActionType.SettleVault, "A15");
require(_args.owner != address(0), "A16");
require(_args.secondAddress != address(0), "A17");

return SettleVaultArgs({owner: _args.owner, vaultId: _args.vaultId, to: _args.secondAddress});
}

function _parseLiquidateArgs(ActionArgs memory _args) internal pure returns (LiquidateArgs memory) {
require(_args.actionType == ActionType.Liquidate, "Actions: can only parse arguments for liquidate action");
require(_args.owner != address(0), "Actions: cannot liquidate vault for an invalid account owner");
require(_args.secondAddress != address(0), "Actions: cannot send collateral to an invalid account");
require(_args.data.length == 32, "Actions: cannot parse liquidate action with no round id");
require(_args.actionType == ActionType.Liquidate, "A18");
require(_args.owner != address(0), "A19");
require(_args.secondAddress != address(0), "A20");
require(_args.data.length == 32, "A21");

// decode chainlink round id from _args.data
uint256 roundId = abi.decode(_args.data, (uint256));
Expand All @@ -320,8 +341,8 @@ library Actions {
* @return arguments for a call action
*/
function _parseCallArgs(ActionArgs memory _args) internal pure returns (CallArgs memory) {
require(_args.actionType == ActionType.Call, "Actions: can only parse arguments for call actions");
require(_args.secondAddress != address(0), "Actions: target address cannot be address(0)");
require(_args.actionType == ActionType.Call, "A22");
require(_args.secondAddress != address(0), "A23");

return CallArgs({callee: _args.secondAddress, data: _args.data});
}
Expand Down
61 changes: 28 additions & 33 deletions contracts/libs/MarginVault.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,19 @@ pragma experimental ABIEncoderV2;

import {SafeMath} from "../packages/oz/SafeMath.sol";

/**
* MarginVault Error Codes
* V1: invalid short otoken amount
* V2: invalid short otoken index
* V3: short otoken address mismatch
* V4: invalid long otoken amount
* V5: invalid long otoken index
* V6: long otoken address mismatch
* V7: invalid collateral amount
* V8: invalid collateral token index
* V9: collateral token address mismatch
*/

/**
* @title MarginVault
* @author Opyn Team
Expand Down Expand Up @@ -47,23 +60,17 @@ library MarginVault {
uint256 _amount,
uint256 _index
) external {
require(_amount > 0, "MarginVault: invalid short otoken amount");
require(_amount > 0, "V1");

// valid indexes in any array are between 0 and array.length - 1.
// if adding an amount to an preexisting short oToken, check that _index is in the range of 0->length-1
if ((_index == _vault.shortOtokens.length) && (_index == _vault.shortAmounts.length)) {
_vault.shortOtokens.push(_shortOtoken);
_vault.shortAmounts.push(_amount);
} else {
require(
(_index < _vault.shortOtokens.length) && (_index < _vault.shortAmounts.length),
"MarginVault: invalid short otoken index"
);
require((_index < _vault.shortOtokens.length) && (_index < _vault.shortAmounts.length), "V2");
address existingShort = _vault.shortOtokens[_index];
require(
(existingShort == _shortOtoken) || (existingShort == address(0)),
"MarginVault: short otoken address mismatch"
);
require((existingShort == _shortOtoken) || (existingShort == address(0)), "V3");

_vault.shortAmounts[_index] = _vault.shortAmounts[_index].add(_amount);
_vault.shortOtokens[_index] = _shortOtoken;
Expand All @@ -84,8 +91,8 @@ library MarginVault {
uint256 _index
) external {
// check that the removed short oToken exists in the vault at the specified index
require(_index < _vault.shortOtokens.length, "MarginVault: invalid short otoken index");
require(_vault.shortOtokens[_index] == _shortOtoken, "MarginVault: short otoken address mismatch");
require(_index < _vault.shortOtokens.length, "V2");
require(_vault.shortOtokens[_index] == _shortOtoken, "V3");

uint256 newShortAmount = _vault.shortAmounts[_index].sub(_amount);

Expand All @@ -108,23 +115,17 @@ library MarginVault {
uint256 _amount,
uint256 _index
) external {
require(_amount > 0, "MarginVault: invalid long otoken amount");
require(_amount > 0, "V4");

// valid indexes in any array are between 0 and array.length - 1.
// if adding an amount to an preexisting short oToken, check that _index is in the range of 0->length-1
if ((_index == _vault.longOtokens.length) && (_index == _vault.longAmounts.length)) {
_vault.longOtokens.push(_longOtoken);
_vault.longAmounts.push(_amount);
} else {
require(
(_index < _vault.longOtokens.length) && (_index < _vault.longAmounts.length),
"MarginVault: invalid long otoken index"
);
require((_index < _vault.longOtokens.length) && (_index < _vault.longAmounts.length), "V5");
address existingLong = _vault.longOtokens[_index];
require(
(existingLong == _longOtoken) || (existingLong == address(0)),
"MarginVault: long otoken address mismatch"
);
require((existingLong == _longOtoken) || (existingLong == address(0)), "V6");

_vault.longAmounts[_index] = _vault.longAmounts[_index].add(_amount);
_vault.longOtokens[_index] = _longOtoken;
Expand All @@ -145,8 +146,8 @@ library MarginVault {
uint256 _index
) external {
// check that the removed long oToken exists in the vault at the specified index
require(_index < _vault.longOtokens.length, "MarginVault: invalid long otoken index");
require(_vault.longOtokens[_index] == _longOtoken, "MarginVault: long otoken address mismatch");
require(_index < _vault.longOtokens.length, "V5");
require(_vault.longOtokens[_index] == _longOtoken, "V6");

uint256 newLongAmount = _vault.longAmounts[_index].sub(_amount);

Expand All @@ -169,23 +170,17 @@ library MarginVault {
uint256 _amount,
uint256 _index
) external {
require(_amount > 0, "MarginVault: invalid collateral amount");
require(_amount > 0, "V7");

// valid indexes in any array are between 0 and array.length - 1.
// if adding an amount to an preexisting short oToken, check that _index is in the range of 0->length-1
if ((_index == _vault.collateralAssets.length) && (_index == _vault.collateralAmounts.length)) {
_vault.collateralAssets.push(_collateralAsset);
_vault.collateralAmounts.push(_amount);
} else {
require(
(_index < _vault.collateralAssets.length) && (_index < _vault.collateralAmounts.length),
"MarginVault: invalid collateral token index"
);
require((_index < _vault.collateralAssets.length) && (_index < _vault.collateralAmounts.length), "V8");
address existingCollateral = _vault.collateralAssets[_index];
require(
(existingCollateral == _collateralAsset) || (existingCollateral == address(0)),
"MarginVault: collateral token address mismatch"
);
require((existingCollateral == _collateralAsset) || (existingCollateral == address(0)), "V9");

_vault.collateralAmounts[_index] = _vault.collateralAmounts[_index].add(_amount);
_vault.collateralAssets[_index] = _collateralAsset;
Expand All @@ -206,8 +201,8 @@ library MarginVault {
uint256 _index
) external {
// check that the removed collateral exists in the vault at the specified index
require(_index < _vault.collateralAssets.length, "MarginVault: invalid collateral asset index");
require(_vault.collateralAssets[_index] == _collateralAsset, "MarginVault: collateral token address mismatch");
require(_index < _vault.collateralAssets.length, "V8");
require(_vault.collateralAssets[_index] == _collateralAsset, "V9");

uint256 newCollateralAmount = _vault.collateralAmounts[_index].sub(_amount);

Expand Down
Loading