Skip to content

Commit

Permalink
Merge branch 'main' into fill-price
Browse files Browse the repository at this point in the history
  • Loading branch information
0xjocke authored Jun 29, 2023
2 parents 004909c + fd6ceab commit 90d4a6c
Show file tree
Hide file tree
Showing 16 changed files with 297 additions and 60 deletions.
9 changes: 7 additions & 2 deletions markets/perps-market/contracts/interfaces/IAccountModule.sol
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ interface IAccountModule {
event CollateralModified(
uint128 indexed accountId,
uint128 indexed synthMarketId,
int indexed amountDelta,
address sender
int amountDelta,
address indexed sender
);

function modifyCollateral(uint128 accountId, uint128 synthMarketId, int amountDelta) external;
Expand All @@ -39,4 +39,9 @@ interface IAccountModule {
) external view returns (AsyncOrder.Data memory);

function getAvailableMargin(uint128 accountId) external view returns (int);

function getCollateralAmount(
uint128 accountId,
uint128 synthMarketId
) external view returns (uint256);
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@ interface IAsyncOrderModule {
event OrderCommitted(
uint128 indexed marketId,
uint128 indexed accountId,
SettlementStrategy.Type indexed orderType,
SettlementStrategy.Type orderType,
int128 sizeDelta,
uint256 acceptablePrice,
uint256 settlementTime,
uint256 expirationTime,
bytes32 trackingCode,
bytes32 indexed trackingCode,
address sender
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,20 +21,24 @@ interface IMarketConfigurationModule {
uint256 indexed strategyId
);

event OrderFeesSet(uint128 marketId, uint256 makerFeeRatio, uint256 takerFeeRatio);
event FundingParametersSet(uint128 marketId, uint256 skewScale, uint256 maxFundingVelocity);
event OrderFeesSet(uint128 indexed marketId, uint256 makerFeeRatio, uint256 takerFeeRatio);
event FundingParametersSet(
uint128 indexed marketId,
uint256 skewScale,
uint256 maxFundingVelocity
);
event LiquidationParametersSet(
uint128 marketId,
uint128 indexed marketId,
uint256 initialMarginRatioD18,
uint256 maintenanceMarginRatioD18,
uint256 liquidationRewardRatioD18,
uint256 maxLiquidationLimitAccumulationMultiplier,
uint256 maxSecondsInLiquidationWindow,
uint256 minimumPositionMargin
);
event MaxMarketValueSet(uint128 marketId, uint256 maxMarketValue);
event LockedOiRatioD18Set(uint128 marketId, uint256 lockedOiRatioD18);
event SettlementStrategyEnabled(uint128 marketId, uint256 strategyId, bool enabled);
event MaxMarketValueSet(uint128 indexed marketId, uint256 maxMarketValue);
event LockedOiRatioD18Set(uint128 indexed marketId, uint256 lockedOiRatioD18);
event SettlementStrategyEnabled(uint128 indexed marketId, uint256 strategyId, bool enabled);

function addSettlementStrategy(
uint128 marketId,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,12 @@ interface IPerpsMarketFactoryModule is IMarket {
string marketName,
string marketSymbol
);
event MarketOwnerNominated(uint128 indexed perpsMarketId, address newNominatedOwner);
event MarketOwnerChanged(uint128 indexed perpsMarketId, address oldOwner, address newOwner);
event MarketOwnerNominated(uint128 indexed perpsMarketId, address indexed newNominatedOwner);
event MarketOwnerChanged(
uint128 indexed perpsMarketId,
address indexed oldOwner,
address indexed newOwner
);
event MarketPriceDataUpdated(uint128 indexed perpsMarketId, bytes32 feedId);

error NotNominated(address notNominatedAddress);
Expand Down
7 changes: 7 additions & 0 deletions markets/perps-market/contracts/modules/PerpsAccountModule.sol
Original file line number Diff line number Diff line change
Expand Up @@ -104,4 +104,11 @@ contract PerpsAccountModule is IAccountModule {
function getAvailableMargin(uint128 accountId) external view override returns (int) {
return PerpsAccount.load(accountId).getAvailableMargin();
}

function getCollateralAmount(
uint128 accountId,
uint128 synthMarketId
) external view override returns (uint256) {
return PerpsAccount.load(accountId).collateralAmounts[synthMarketId];
}
}
9 changes: 8 additions & 1 deletion markets/perps-market/contracts/storage/AsyncOrder.sol
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ library AsyncOrder {
if (order.sizeDelta == 0) {
revert ZeroSizeOrder();
}

SimulateDataRuntime memory runtime;

PerpsAccount.Data storage account = PerpsAccount.load(order.accountId);
Expand Down Expand Up @@ -196,9 +197,15 @@ library AsyncOrder {
revert InsufficientMargin(runtime.currentAvailableMargin, runtime.orderFees);
}

// TODO: validate position size
oldPosition = PerpsMarket.load(order.marketId).positions[order.accountId];

PerpsMarket.validatePositionSize(
perpsMarketData,
marketConfig.maxMarketValue,
oldPosition.size,
order.sizeDelta
);

runtime.newPositionSize = oldPosition.size + order.sizeDelta;
(, , runtime.initialRequiredMargin, , ) = marketConfig.calculateRequiredMargins(
runtime.newPositionSize,
Expand Down
62 changes: 31 additions & 31 deletions markets/perps-market/contracts/storage/PerpsMarket.sol
Original file line number Diff line number Diff line change
Expand Up @@ -233,43 +233,43 @@ library PerpsMarket {
return (block.timestamp - self.lastFundingTime).toInt().divDecimal(1 days);
}

// TODO: David will refactor this
function validatePositionSize(
Data storage self,
uint maxSize,
int oldSize,
int newSize
) internal view returns (bool) {
) internal view {
// Allow users to reduce an order no matter the market conditions.
if (MathUtil.sameSide(oldSize, newSize) && MathUtil.abs(newSize) <= MathUtil.abs(oldSize)) {
return false;
bool isNotReducingInterest = !(MathUtil.sameSide(oldSize, newSize) &&
MathUtil.abs(newSize) <= MathUtil.abs(oldSize));
if (isNotReducingInterest) {
int newSkew = self.skew - oldSize + newSize;

int newMarketSize = self.size.toInt() -
MathUtil.abs(oldSize).toInt() +
MathUtil.abs(newSize).toInt();

int newSideSize;
if (0 < newSize) {
// long case: marketSize + skew
// = (|longSize| + |shortSize|) + (longSize + shortSize)
// = 2 * longSize
newSideSize = newMarketSize + newSkew;
} else {
// short case: marketSize - skew
// = (|longSize| + |shortSize|) - (longSize + shortSize)
// = 2 * -shortSize
newSideSize = newMarketSize - newSkew;
}

// newSideSize still includes an extra factor of 2 here, so we will divide by 2 in the actual condition
if (maxSize < MathUtil.abs(newSideSize / 2)) {
revert PerpsMarketConfiguration.MaxOpenInterestReached(
self.id,
maxSize,
newSideSize / 2
);
}
}

// Either the user is flipping sides, or they are increasing an order on the same side they're already on;
// we check that the side of the market their order is on would not break the limit.
int newSkew = self.skew - oldSize + newSize;
int newMarketSize = self.size.toInt() -
MathUtil.abs(oldSize).toInt() +
MathUtil.abs(newSize).toInt();

int newSideSize;
if (0 < newSize) {
// long case: marketSize + skew
// = (|longSize| + |shortSize|) + (longSize + shortSize)
// = 2 * longSize
newSideSize = newMarketSize + newSkew;
} else {
// short case: marketSize - skew
// = (|longSize| + |shortSize|) - (longSize + shortSize)
// = 2 * -shortSize
newSideSize = newMarketSize - newSkew;
}

// newSideSize still includes an extra factor of 2 here, so we will divide by 2 in the actual condition
if (maxSize < MathUtil.abs(newSideSize / 2)) {
return true;
}

return false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ library PerpsMarketConfiguration {
using DecimalMath for uint256;
using SafeCastI128 for int128;

error MaxOpenInterestReached(uint128 marketId, uint256 maxMarketValue, int newSideSize);

error InvalidSettlementStrategy(uint128 settlementStrategyId);

struct Data {
Expand Down
2 changes: 1 addition & 1 deletion markets/perps-market/storage.dump.sol
Original file line number Diff line number Diff line change
Expand Up @@ -350,7 +350,7 @@ library Vault {
struct Data {
uint256 epoch;
bytes32 __slotAvailableForFutureUse;
int128 prevTotalDebtD18;
int128 _unused_prevTotalDebtD18;
mapping(uint256 => VaultEpoch.Data) epochData;
mapping(bytes32 => RewardDistribution.Data) rewards;
SetUtil.Bytes32Set rewardIds;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,5 +109,13 @@ describe('ModifyCollateral Deposit', () => {
systems().PerpsMarket
);
});

it('returns the correct amount when calling getCollateralAmount', async () => {
const collateralBalance = await systems().PerpsMarket.getCollateralAmount(
accountIds[0],
synthBTCMarketId
);
assertBn.equal(collateralBalance, bn(1));
});
});
});
20 changes: 20 additions & 0 deletions markets/perps-market/test/integration/Market/CreateMarket.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,22 @@ describe('Create Market test', () => {
);
});
});

describe('after market is created', () => {
before('set max market value', async () => {
tx = await systems()
.PerpsMarket.connect(marketOwner)
.setMaxMarketValue(marketId, bn(99999999));
});

it('should emit MaxMarketValueSet event', async () => {
await assertEvent(
tx,
`MaxMarketValueSet(${marketId}, ${bn(99999999).toString()})`,
systems().PerpsMarket
);
});
});
});

describe('change ownership', async () => {
Expand Down Expand Up @@ -178,6 +194,10 @@ describe('Create Market test', () => {
await systems().PerpsMarket.createMarket(name, token, marketOwner.getAddress());
});

before('set max market value', async () => {
await systems().PerpsMarket.connect(marketOwner).setMaxMarketValue(marketId, bn(99999999));
});

before('create price nodes', async () => {
const results = await createOracleNode(owner(), price, systems().OracleManager);
oracleNodeId = results.oracleNodeId;
Expand Down
Loading

0 comments on commit 90d4a6c

Please sign in to comment.