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

Remove absolute position update #512

Open
wants to merge 33 commits into
base: v2.4
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 28 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
46a8952
remove absolute position update, add maker delta update and updated c…
prateekdefi Dec 11, 2024
2781eea
update multiInvoker contracts
prateekdefi Dec 11, 2024
388dcb7
update vault contracts
prateekdefi Dec 11, 2024
a362d40
update test marketHelpers
prateekdefi Dec 11, 2024
50da105
fix maker referral fee
prateekdefi Dec 11, 2024
e830d03
fix multiInvoker integration tests
prateekdefi Dec 11, 2024
a509791
fix collateral accounts integration tests
prateekdefi Dec 11, 2024
f390103
fix trigger orders integration tests
prateekdefi Dec 11, 2024
574cc30
fix vault integration tests
prateekdefi Dec 11, 2024
74e1564
fix oracle integration tests
prateekdefi Dec 11, 2024
bd95dea
update workflow to run tests on CI
prateekdefi Dec 11, 2024
255fb28
add close with referrer method
prateekdefi Dec 12, 2024
5570684
update tests with new close method
prateekdefi Dec 12, 2024
7efa228
fix some core integration tests
prateekdefi Dec 12, 2024
71db5bf
Merge branch 'prateek/pe-1629-remove-magic-values' into prateek/pe-16…
prateekdefi Dec 16, 2024
722ede7
disable CI
prateekdefi Dec 16, 2024
9191e0e
update comment and remove absolute order
prateekdefi Dec 16, 2024
3404c09
update tests with delta update
prateekdefi Dec 17, 2024
2675308
Merge branch 'prateek/pe-1629-remove-magic-values' into prateek/pe-16…
prateekdefi Dec 17, 2024
58c2f0b
update workflow to run tests on CI
prateekdefi Dec 17, 2024
7fb6985
update contracts with new delta update
prateekdefi Dec 17, 2024
3856ad8
fix oracle and vault tests
prateekdefi Dec 18, 2024
09cb5cb
fix trigger order close position
prateekdefi Dec 18, 2024
4774f86
fix core integration tests
prateekdefi Dec 18, 2024
5713d01
fix core unit tests
prateekdefi Dec 20, 2024
81650f0
PR feedback
prateekdefi Dec 24, 2024
6f00446
Merge branch 'v2.4' into prateek/pe-1630-remove-absolute-position-update
prateekdefi Dec 24, 2024
6564682
fix insurance fund tests
prateekdefi Dec 24, 2024
f3b02b1
PR feedback
prateekdefi Dec 30, 2024
3cd9189
Merge branch 'v2.4' into prateek/pe-1630-remove-absolute-position-update
prateekdefi Jan 6, 2025
0878a92
fix tests
prateekdefi Jan 6, 2025
84f256c
rename position
prateekdefi Jan 8, 2025
62c630c
update workflow
prateekdefi Jan 8, 2025
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
1 change: 1 addition & 0 deletions .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ on:
branches:
- main
- v2.4
- prateek/pe-1629-remove-magic-values
workflow_dispatch:

env:
Expand Down
63 changes: 4 additions & 59 deletions packages/core/contracts/Market.sol
Original file line number Diff line number Diff line change
Expand Up @@ -173,16 +173,16 @@ contract Market is IMarket, Instance, ReentrancyGuard {

/// @notice Updates the account's position and collateral
/// @param account The account to operate on
/// @param amount The position delta of the order (positive for long, negative for short)
/// @param takerAmount The position delta of the order (positive for long, negative for short)
/// @param collateral The collateral delta of the order (positive for deposit, negative for withdrawal)
/// @param referrer The referrer of the order
function update(
address account,
Fixed6 amount,
Fixed6 takerAmount,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what if we went the other direction for these and named them taker and maker like you did in the Trigger Order code for both overloads? might be a little more succint.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the trigger orders i have used makerDelta and takerDelta. I think taker and maker are used in multiInvoker here. I agree that it will be more succinct but I like takerAmount more than taker as it helps with readability and think that we should rename to takerAmount in multiInvoker as well.

Fixed6 collateral,
address referrer
) external {
update(account, Fixed6Lib.ZERO, amount, collateral, referrer);
update(account, Fixed6Lib.ZERO, takerAmount, collateral, referrer);
}

/// @notice Updates the account's position and collateral
Expand Down Expand Up @@ -217,61 +217,6 @@ contract Market is IMarket, Instance, ReentrancyGuard {
_updateAndStore(context, updateContext, newOrder, newGuarantee, referrer, address(0));
}

/// @notice Updates the account's position and collateral
/// @param account The account to operate on
/// @param newMaker The new maker position for the account
/// @param newMaker The new long position for the account
/// @param newMaker The new short position for the account
/// @param collateral The collateral amount to add or remove from the account
/// @param protect Whether to put the account into a protected status for liquidations
function update(
address account,
UFixed6 newMaker,
UFixed6 newLong,
UFixed6 newShort,
Fixed6 collateral,
bool protect
) external {
update(account, newMaker, newLong, newShort, collateral, protect, address(0));
}

/// @notice Updates the account's position and collateral
/// @param account The account to operate on
/// @param newMaker The new maker position for the account
/// @param newLong The new long position for the account
/// @param newShort The new short position for the account
/// @param collateral The collateral amount to add or remove from the account
/// @param protect Whether to put the account into a protected status for liquidations
/// @param referrer The referrer of the order
function update(
address account,
UFixed6 newMaker,
UFixed6 newLong,
UFixed6 newShort,
Fixed6 collateral,
bool protect,
address referrer
) public nonReentrant whenNotPaused {
(Context memory context, UpdateContext memory updateContext) =
_loadForUpdate(account, address(0), referrer, address(0), UFixed6Lib.ZERO, UFixed6Lib.ZERO);

// create new order & guarantee
Order memory newOrder = OrderLib.from(
context.currentTimestamp,
updateContext.currentPositionLocal,
collateral,
newMaker,
newLong,
newShort,
protect,
updateContext.orderReferralFee
);
Guarantee memory newGuarantee; // no guarantee is created for a market order

// process update
_updateAndStore(context, updateContext, newOrder, newGuarantee, referrer, address(0));
}

/// @notice Closes the account's position
/// @param account The account to operate on
/// @param protect Whether to put the account into a protected status for liquidations
Expand All @@ -284,7 +229,7 @@ contract Market is IMarket, Instance, ReentrancyGuard {
Fixed6 takerAmount;

UFixed6 closable = context.latestPositionLocal.magnitude().sub(context.pendingLocal.neg());

if (updateContext.currentPositionLocal.maker.gt(UFixed6Lib.ZERO)) {
makerAmount = Fixed6Lib.from(-1, closable);
} else if (updateContext.currentPositionLocal.long.gt(UFixed6Lib.ZERO)) {
Expand Down
4 changes: 1 addition & 3 deletions packages/core/contracts/interfaces/IMarket.sol
Original file line number Diff line number Diff line change
Expand Up @@ -160,10 +160,8 @@ interface IMarket is IInstance {
function guaranteeReferrers(address account, uint256 id) external view returns (address);
function settle(address account) external;
function update(address account, Intent calldata intent, bytes memory signature) external;
function update(address account, Fixed6 amount, Fixed6 collateral, address referrer) external;
function update(address account, Fixed6 takerAmount, Fixed6 collateral, address referrer) external;
function update(address account, Fixed6 makerAmount, Fixed6 takerAmount, Fixed6 collateral, address referrer) external;
function update(address account, UFixed6 newMaker, UFixed6 newLong, UFixed6 newShort, Fixed6 collateral, bool protect) external;
function update(address account, UFixed6 newMaker, UFixed6 newLong, UFixed6 newShort, Fixed6 collateral, bool protect, address referrer) external;
function close(address account, bool protect, address referrer) external;
function parameter() external view returns (MarketParameter memory);
function riskParameter() external view returns (RiskParameter memory);
Expand Down
10 changes: 5 additions & 5 deletions packages/core/contracts/test/MockToken.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,23 @@ import { IMarket } from "../interfaces/IMarket.sol";

contract MockToken is ERC20 {

enum Function{ SETTLE, UPDATE, UPDATE_MAKER, UPDATE_INTENT }
enum Function{ SETTLE, UPDATE, UPDATE_INTENT, CLOSE }

Function private functionToCall;

constructor() ERC20("MockToken", "MTOKEN") {}

function transferFrom(address, address, uint256) public override returns (bool) {
// call method of market contract for reentrancy
if (functionToCall == Function.UPDATE_MAKER) {
IMarket(msg.sender).update(address(0), UFixed6Lib.from(0), UFixed6Lib.from(0), UFixed6Lib.from(0), Fixed6Lib.from(0), false);
} else if (functionToCall == Function.UPDATE) {
IMarket(msg.sender).update(address(0), Fixed6Lib.from(0), Fixed6Lib.from(0), address(0));
if (functionToCall == Function.UPDATE) {
IMarket(msg.sender).update(address(0), Fixed6Lib.from(0), Fixed6Lib.from(0), Fixed6Lib.from(0), address(0));
} else if (functionToCall == Function.UPDATE_INTENT) {
Intent memory intent;
IMarket(msg.sender).update(address(0), intent, "");
} else if (functionToCall == Function.SETTLE){
IMarket(msg.sender).settle(address(0));
} else if (functionToCall == Function.CLOSE) {
IMarket(msg.sender).close(address(0), false, address(0));
}

return true;
Expand Down
50 changes: 3 additions & 47 deletions packages/core/contracts/types/Order.sol
Original file line number Diff line number Diff line change
Expand Up @@ -80,12 +80,13 @@ library OrderLib {
(UFixed6Lib.ZERO, UFixed6Lib.ZERO, UFixed6Lib.ZERO, UFixed6Lib.ZERO, UFixed6Lib.ZERO, UFixed6Lib.ZERO);
}

/// @notice Creates a new order from the an intent order request
/// @notice Creates a new order from an intent or delta order request
/// @param timestamp The current timestamp
/// @param position The current position
/// @param makerAmount The magnitude and direction of maker position
/// @param takerAmount The magnitude and direction of taker position
/// @param collateral The change in the collateral
/// @param protect True when liquidating the position
/// @param referralFee The referral fee
/// @return newOrder The resulting order
function from(
Expand All @@ -100,9 +101,9 @@ library OrderLib {
newOrder.timestamp = timestamp;
newOrder.collateral = collateral;
newOrder.orders = makerAmount.isZero() && takerAmount.isZero() ? 0 : 1;
newOrder.protection = protect ? 1 : 0;
newOrder.makerReferral = makerAmount.abs().mul(referralFee);
newOrder.takerReferral = takerAmount.abs().mul(referralFee);
newOrder.protection = protect ? 1 : 0;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we need to change the order here? might want to leave in the original slot just to reduce the changeset.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it happened while merging, reverting to old order.


// If the order is not counter to the current position, it is opening
if (takerAmount.sign() == 0 || position.skew().sign() == 0 || position.skew().sign() == takerAmount.sign()) {
Expand All @@ -119,51 +120,6 @@ library OrderLib {
newOrder.makerNeg = makerAmount.min(Fixed6Lib.ZERO).abs();
prateekdefi marked this conversation as resolved.
Show resolved Hide resolved
}

/// @notice Creates a new order from the current position and an update request
/// @param timestamp The current timestamp
/// @param position The current position
/// @param collateral The change in the collateral
/// @param newMaker The new maker
/// @param newLong The new long
/// @param newShort The new short
/// @param protect Whether to protect the order
/// @param referralFee The referral fee
/// @return newOrder The resulting order
function from(
uint256 timestamp,
Position memory position,
Fixed6 collateral,
UFixed6 newMaker,
UFixed6 newLong,
UFixed6 newShort,
bool protect,
UFixed6 referralFee
) internal pure returns (Order memory newOrder) {
(Fixed6 makerAmount, Fixed6 longAmount, Fixed6 shortAmount) = (
Fixed6Lib.from(newMaker).sub(Fixed6Lib.from(position.maker)),
Fixed6Lib.from(newLong).sub(Fixed6Lib.from(position.long)),
Fixed6Lib.from(newShort).sub(Fixed6Lib.from(position.short))
);

UFixed6 referral = makerAmount.abs().add(longAmount.abs()).add(shortAmount.abs()).mul(referralFee);

newOrder = Order(
timestamp,
0,
collateral,
makerAmount.max(Fixed6Lib.ZERO).abs(),
makerAmount.min(Fixed6Lib.ZERO).abs(),
longAmount.max(Fixed6Lib.ZERO).abs(),
longAmount.min(Fixed6Lib.ZERO).abs(),
shortAmount.max(Fixed6Lib.ZERO).abs(),
shortAmount.min(Fixed6Lib.ZERO).abs(),
protect ? 1 : 0,
makerAmount.isZero() ? UFixed6Lib.ZERO : referral,
makerAmount.isZero() ? referral : UFixed6Lib.ZERO
);
if (!isEmpty(newOrder)) newOrder.orders = 1;
}

/// @notice Returns whether the order increases any of the account's positions
/// @return Whether the order increases any of the account's positions
function increasesPosition(Order memory self) internal pure returns (bool) {
Expand Down
32 changes: 13 additions & 19 deletions packages/core/test/integration/core/closedProduct.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { expect } from 'chai'
import 'hardhat'
import { BigNumber, constants } from 'ethers'
const { AddressZero } = constants

Check warning on line 4 in packages/core/test/integration/core/closedProduct.test.ts

View workflow job for this annotation

GitHub Actions / Lint

'AddressZero' is assigned a value but never used

import { InstanceVars, deployProtocol, createMarket, settle } from '../helpers/setupHelpers'
import { Market } from '../../../types/generated'
Expand All @@ -21,13 +21,13 @@
it('closes the market', async () => {
const POSITION = parse6decimal('10')
const COLLATERAL = parse6decimal('1000')
const { owner, user, dsu, chainlink, beneficiaryB } = instanceVars

Check warning on line 24 in packages/core/test/integration/core/closedProduct.test.ts

View workflow job for this annotation

GitHub Actions / Lint

'beneficiaryB' is assigned a value but never used

const market = await createMarket(instanceVars)
await dsu.connect(user).approve(market.address, COLLATERAL.mul(1e12))
await market
.connect(user)
['update(address,uint256,uint256,uint256,int256,bool)'](user.address, POSITION, 0, 0, COLLATERAL, false)
['update(address,int256,int256,int256,address)'](user.address, POSITION, 0, COLLATERAL, constants.AddressZero)

expect((await market.parameter()).closed).to.be.false

Expand All @@ -49,17 +49,17 @@
const COLLATERAL = parse6decimal('1000')

beforeEach(async () => {
const { user, userB, dsu, beneficiaryB } = instanceVars

Check warning on line 52 in packages/core/test/integration/core/closedProduct.test.ts

View workflow job for this annotation

GitHub Actions / Lint

'beneficiaryB' is assigned a value but never used

market = await createMarket(instanceVars)
await dsu.connect(user).approve(market.address, COLLATERAL.mul(1e12))
await dsu.connect(userB).approve(market.address, COLLATERAL.mul(1e12))
await market
.connect(user)
['update(address,uint256,uint256,uint256,int256,bool)'](user.address, POSITION, 0, 0, COLLATERAL, false)
['update(address,int256,int256,int256,address)'](user.address, POSITION, 0, COLLATERAL, constants.AddressZero)
await market
.connect(userB)
['update(address,uint256,uint256,uint256,int256,bool)'](userB.address, 0, POSITION, 0, COLLATERAL, false)
['update(address,int256,int256,int256,address)'](userB.address, 0, POSITION, COLLATERAL, constants.AddressZero)
const parameters = { ...(await market.parameter()) }
parameters.closed = true
await market.updateParameter(parameters)
Expand All @@ -73,7 +73,7 @@
await expect(
market
.connect(user)
['update(address,uint256,uint256,uint256,int256,bool)'](user.address, 0, POSITION, 0, 0, false),
['update(address,int256,int256,int256,address)'](user.address, 0, POSITION, 0, constants.AddressZero),
).to.be.revertedWithCustomError(market, 'MarketClosedError')
})

Expand All @@ -82,28 +82,24 @@

await chainlink.next()

await expect(
await market
.connect(user)
['update(address,uint256,uint256,uint256,int256,bool)'](user.address, 0, 0, 0, 0, false),
).to.not.be.reverted
await expect(await market.connect(user).close(user.address, false, constants.AddressZero)).to.not.be.reverted
})
})

it('zeroes PnL and fees', async () => {
const POSITION = parse6decimal('10')
const COLLATERAL = parse6decimal('1000')
const { user, userB, chainlink, dsu, beneficiaryB } = instanceVars

Check warning on line 92 in packages/core/test/integration/core/closedProduct.test.ts

View workflow job for this annotation

GitHub Actions / Lint

'beneficiaryB' is assigned a value but never used

const market = await createMarket(instanceVars)
await dsu.connect(user).approve(market.address, COLLATERAL.mul(1e12))
await dsu.connect(userB).approve(market.address, COLLATERAL.mul(1e12))
await market
.connect(user)
['update(address,uint256,uint256,uint256,int256,bool)'](user.address, POSITION, 0, 0, COLLATERAL, false)
['update(address,int256,int256,int256,address)'](user.address, POSITION, 0, COLLATERAL, constants.AddressZero)
await market
.connect(userB)
['update(address,uint256,uint256,uint256,int256,bool)'](userB.address, 0, POSITION, 0, COLLATERAL, false)
['update(address,int256,int256,int256,address)'](userB.address, 0, POSITION, COLLATERAL, constants.AddressZero)

await chainlink.next()
await chainlink.next()
Expand All @@ -122,9 +118,9 @@
await chainlink.nextWithPriceModification(price => price.mul(4))
await chainlink.nextWithPriceModification(price => price.mul(4))

const LIQUIDATION_FEE = BigNumber.from('1000000000')

Check warning on line 121 in packages/core/test/integration/core/closedProduct.test.ts

View workflow job for this annotation

GitHub Actions / Lint

'LIQUIDATION_FEE' is assigned a value but never used
await market.connect(user)['update(address,uint256,uint256,uint256,int256,bool)'](user.address, 0, 0, 0, 0, true)
await market.connect(userB)['update(address,uint256,uint256,uint256,int256,bool)'](userB.address, 0, 0, 0, 0, true)
await market.connect(user).close(user.address, true, constants.AddressZero)
await market.connect(userB).close(userB.address, true, constants.AddressZero)

expect((await market.locals(user.address)).collateral).to.equal(userCollateralBefore)
expect((await market.locals(userB.address)).collateral).to.equal(userBCollateralBefore)
Expand All @@ -136,23 +132,21 @@
it('handles closing during liquidations', async () => {
const POSITION = parse6decimal('10')
const COLLATERAL = parse6decimal('1000')
const { user, userB, chainlink, dsu, beneficiaryB } = instanceVars

Check warning on line 135 in packages/core/test/integration/core/closedProduct.test.ts

View workflow job for this annotation

GitHub Actions / Lint

'beneficiaryB' is assigned a value but never used

const market = await createMarket(instanceVars)
await dsu.connect(user).approve(market.address, COLLATERAL.mul(1e12))
await dsu.connect(userB).approve(market.address, COLLATERAL.mul(1e12))
await market
.connect(user)
['update(address,uint256,uint256,uint256,int256,bool)'](user.address, POSITION, 0, 0, COLLATERAL, false)
['update(address,int256,int256,int256,address)'](user.address, POSITION, 0, COLLATERAL, constants.AddressZero)
await market
.connect(userB)
['update(address,uint256,uint256,uint256,int256,bool)'](userB.address, 0, POSITION, 0, COLLATERAL, false)
['update(address,int256,int256,int256,address)'](userB.address, 0, POSITION, COLLATERAL, constants.AddressZero)

await chainlink.next()
await chainlink.nextWithPriceModification(price => price.mul(2))
await expect(
market.connect(userB)['update(address,uint256,uint256,uint256,int256,bool)'](user.address, 0, 0, 0, 0, true),
).to.not.be.reverted
await expect(market.connect(userB).close(user.address, true, constants.AddressZero)).to.not.be.reverted
expect((await market.pendingOrders(user.address, 2)).protection).to.eq(1)
const parameters = { ...(await market.parameter()) }
parameters.closed = true
Expand All @@ -173,9 +167,9 @@
await chainlink.nextWithPriceModification(price => price.mul(4))
await chainlink.nextWithPriceModification(price => price.mul(4))

const LIQUIDATION_FEE = BigNumber.from('1000000000')

Check warning on line 170 in packages/core/test/integration/core/closedProduct.test.ts

View workflow job for this annotation

GitHub Actions / Lint

'LIQUIDATION_FEE' is assigned a value but never used
await settle(market, user)
await market.connect(userB)['update(address,uint256,uint256,uint256,int256,bool)'](userB.address, 0, 0, 0, 0, true)
await market.connect(userB).close(userB.address, true, constants.AddressZero)

expect((await market.locals(user.address)).collateral).to.equal(userCollateralBefore)
expect((await market.locals(userB.address)).collateral).to.equal(userBCollateralBefore)
Expand Down
Loading
Loading