Skip to content

Commit d69a51e

Browse files
authored
🚀 Mykonos Upgrade (v2.1.0)
2 parents 36b0491 + 4d43b53 commit d69a51e

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

59 files changed

+4365
-1200
lines changed

.gas-snapshot

Lines changed: 182 additions & 143 deletions
Large diffs are not rendered by default.

.github/workflows/test.yml

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -27,17 +27,18 @@ jobs:
2727

2828
- name: Run forge test
2929
run: |
30-
forge test --fork-url ${{ secrets.ARCHIVE_NODE_URL_GOERLI_L2 }} --etherscan-api-key ${{ secrets.ETHERSCAN_API_KEY }} -vvv
30+
forge test --fork-url ${{ secrets.ARCHIVE_NODE_URL_L2 }} --etherscan-api-key ${{ secrets.ETHERSCAN_API_KEY }} -vvv
3131
id: test
32-
33-
- name: Run forge coverage
34-
run: |
35-
forge coverage --fork-url ${{ secrets.ARCHIVE_NODE_URL_GOERLI_L2 }} --report lcov
36-
37-
- name: Upload Coverage Report
38-
uses: codecov/codecov-action@v3
39-
with:
40-
files: ./lcov.info
41-
name: codecov-unit
42-
fail_ci_if_error: true
43-
verbose: true
32+
33+
# FIXME: Coverage is broken due to stack too deep error
34+
# - name: Run forge coverage
35+
# run: |
36+
# forge coverage --fork-url ${{ secrets.ARCHIVE_NODE_URL_L2 }} --report lcov
37+
38+
# - name: Upload Coverage Report
39+
# uses: codecov/codecov-action@v3
40+
# with:
41+
# files: ./lcov.info
42+
# name: codecov-unit
43+
# fail_ci_if_error: true
44+
# verbose: true

README.md

Lines changed: 40 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ Contracts to manage account abstractions and features on top of [Synthetix Perps
2525

2626
> See ./deploy-addresses/ for deployed contract addresses
2727
28-
The Margin Manager codebase consists of the `Factory` and `Account` contracts, and all of the associated dependencies. The purpose of the `Factory` is to create/deploy trading accounts (`Account` contracts) for users that support features ranging from cross-margin, conditional orders, copy trading, etc.. Once a smart margin account has been created, the main point of entry is the `Account.execute` function. `Account.execute` allows users to execute a set of commands describing the actions/trades they want executed by their account.
28+
The Smart Margin codebase consists of the `Factory` and `Account` contracts, and all of the associated dependencies. The purpose of the `Factory` is to create/deploy trading accounts (`Account` contracts) for users that support features ranging from cross-margin, conditional orders, copy trading, etc.. Once a smart margin account has been created, the main point of entry is the `Account.execute` function. `Account.execute` allows users to execute a set of commands describing the actions/trades they want executed by their account.
2929

3030
### User Entry: MarginBase Command Execution
3131

@@ -36,24 +36,7 @@ Calls to `Account.execute`, the entrypoint to the smart margin account, require
3636

3737
`commands[i]` is the command that will use `inputs[i]` as its encoded input parameters.
3838

39-
The supported commands can be found below (ordering may _not_ match what is defined in `IAccount.sol`):
40-
41-
```
42-
ACCOUNT_MODIFY_MARGIN
43-
ACCOUNT_WITHDRAW_ETH
44-
PERPS_V2_MODIFY_MARGIN
45-
PERPS_V2_WITHDRAW_ALL_MARGIN
46-
PERPS_V2_SUBMIT_ATOMIC_ORDER
47-
PERPS_V2_SUBMIT_DELAYED_ORDER
48-
PERPS_V2_SUBMIT_OFFCHAIN_DELAYED_ORDER
49-
PERPS_V2_CLOSE_POSITION
50-
PERPS_V2_SUBMIT_CLOSE_DELAYED_ORDER
51-
PERPS_V2_SUBMIT_CLOSE_OFFCHAIN_DELAYED_ORDER
52-
PERPS_V2_CANCEL_DELAYED_ORDER
53-
PERPS_V2_CANCEL_OFFCHAIN_DELAYED_ORDER
54-
GELATO_PLACE_CONDITIONAL_ORDER
55-
GELATO_CANCEL_CONDITIONAL_ORDER
56-
```
39+
The supported commands can be found in the [wiki](https://github.com/Kwenta/smart-margin/wiki/Commands) and [code](https://github.com/Kwenta/smart-margin/blob/main/src/interfaces/IAccount.sol).
5740

5841
#### How the input bytes are structured
5942

@@ -73,7 +56,7 @@ Encoding parameters in a bytes string in this way gives us maximum flexiblity to
7356

7457
For a more detailed breakdown of which parameters you should provide for each command take a look at the `Account.dispatch` function.
7558

76-
Developer documentation to give a detailed explanation of the inputs for every command can be found in the [wiki](https://github.com/Kwenta/margin-manager/wiki/Commands)
59+
Developer documentation to give a detailed explanation of the inputs for every command can also be found in the [wiki](https://github.com/Kwenta/margin-manager/wiki/Commands)
7760

7861
#### Diagram
7962

@@ -100,8 +83,10 @@ Smart margin accounts are upgradable. This is achieved by using a proxy pattern,
10083
Finally, all associated functionality related to upgradability can be disabled by the `Factory` contract owner.
10184

10285
## Folder Structure
86+
> to run: `tree src/`
87+
10388
```
104-
src
89+
src/
10590
├── Account.sol
10691
├── AccountProxy.sol
10792
├── Events.sol
@@ -110,31 +95,36 @@ src
11095
├── interfaces
11196
│ ├── IAccount.sol
11297
│ ├── IAccountProxy.sol
98+
│ ├── IERC20.sol
11399
│ ├── IEvents.sol
114100
│ ├── IFactory.sol
115-
│ ├── IOps.sol
116101
│ ├── ISettings.sol
117-
│ └── synthetix
118-
│ ├── IFuturesMarketManager.sol
119-
│ ├── IPerpsV2MarketConsolidated.sol
120-
│ └── ISystemStatus.sol
102+
│ ├── gelato
103+
│ │ └── IOps.sol
104+
│ ├── synthetix
105+
│ │ ├── IFuturesMarketManager.sol
106+
│ │ ├── IPerpsV2ExchangeRate.sol
107+
│ │ ├── IPerpsV2MarketConsolidated.sol
108+
│ │ └── ISystemStatus.sol
109+
│ ├── token
110+
│ │ └── IERC20.sol
111+
│ └── uniswap
112+
│ ├── IPermit2.sol
113+
│ └── IUniversalRouter.sol
121114
└── utils
122115
├── Auth.sol
123-
└── OpsReady.sol
116+
├── Owned.sol
117+
├── executors
118+
│ └── OrderExecution.sol
119+
├── gelato
120+
│ └── OpsReady.sol
121+
└── uniswap
122+
├── BytesLib.sol
123+
├── Constants.sol
124+
├── SafeCast160.sol
125+
└── V3Path.sol
124126
```
125127

126-
## Test Coverage
127-
128-
| File | % Lines | % Statements | % Branches | % Funcs |
129-
|--------------------------------------|------------------|------------------|------------------|-----------------|
130-
| src/Account.sol | 99.05% (209/211) | 99.10% (221/223) | 93.59% (73/78) | 100.00% (35/35) |
131-
| src/AccountProxy.sol | 100.00% (10/10) | 76.92% (10/13) | 50.00% (3/6) | 100.00% (6/6) |
132-
| src/Events.sol | 100.00% (6/6) | 100.00% (6/6) | 100.00% (0/0) | 100.00% (6/6) |
133-
| src/Factory.sol | 100.00% (27/27) | 100.00% (34/34) | 85.71% (12/14) | 100.00% (6/6) |
134-
| src/Settings.sol | 100.00% (2/2) | 100.00% (2/2) | 100.00% (0/0) | 100.00% (1/1) |
135-
| src/utils/Auth.sol | 100.00% (15/15) | 100.00% (18/18) | 100.00% (10/10) | 100.00% (5/5) |
136-
| src/utils/OpsReady.sol | 100.00% (3/3) | 100.00% (4/4) | 75.00% (3/4) | 100.00% (1/1) |
137-
138128
## Usage
139129

140130
### Setup
@@ -164,7 +154,7 @@ npm run test
164154
4. Run specific test
165155

166156
```
167-
forge test --fork-url $(grep ARCHIVE_NODE_URL_GOERLI_L2 .env | cut -d '=' -f2) --match-test TEST_NAME -vvv
157+
forge test --fork-url $(grep ARCHIVE_NODE_URL_L2 .env | cut -d '=' -f2) --match-test TEST_NAME -vvv
168158
```
169159

170160
> tests will fail if you have not set up your .env (see .env.example)
@@ -195,6 +185,16 @@ forge test --fork-url $(grep ARCHIVE_NODE_URL_GOERLI_L2 .env | cut -d '=' -f2) -
195185
13. Update `./deploy-addresses/optimism.json` with new `Account` address
196186
14. Ensure mainnet accounts are updated and functional (ensure state is correct)
197187

188+
## External Conditional Order Executors
189+
> As of SM v2.1.0, public actors can execute conditional orders and receive a fee for doing so
190+
1. Navigate to `src/utils/executors/OrderExecution.sol`
191+
2. `OrderExecution` is a *simplified* contract which defines: (1) basic batch conditional order execution functionality, (2) a method to update onchain Pyth oracle price feed(s), (3) **combined** price feed update(s) and then conditional order execution functionality
192+
> `OrderExecution` is meant to serve as a starting point for developers to build their own conditional order executors and IS NOT production ready nor has it been audited
193+
3. See https://docs.pyth.network/evm/update-price-feeds for more information on updating Pyth oracle price feeds
194+
4. See `IAccount.executeConditionalOrder` for more information on conditional order execution
195+
5. Currently there are no scripts in this repository which deploy the `OrderExecution` contract
196+
6. See https://github.com/JaredBorders/KwentaOrderExecutor for a conditional order executor that includes deployment scripts
197+
198198
## Project Tools
199199

200200
### Static Analysis

audits/v1.0.0/Kwenta_A-3.pdf

463 KB
Binary file not shown.
Binary file not shown.

audits/v2.0.0/Kwenta_A-4.pdf

547 KB
Binary file not shown.

audits/v2.0.2/Kwenta_A-5.pdf

298 KB
Binary file not shown.

audits/v2.1.0/Kwenta_A-6.pdf

389 KB
Binary file not shown.

deploy-addresses/optimism-goerli.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
2-
"Account": "0xf9CC1eD5EC9b8DFb9273fdDABD07C7bB37938285",
3-
"Events": "0xa7AE3969A128048290968b41865Eaa53B20FA69e",
2+
"Account": "0x0fCeF9608B9F7a8C57D53B98E78fA64b4D786a9F",
3+
"Events": "0xe32F27B27F4ea5f10f269b52223910bA83e2933C",
44
"Factory": "0x30582eeE34719fe22b1B6c3b607636A3ab94522E",
5-
"Settings": "0xd2f3c4D549EF6AB572dB6512AB0e33f709E7caE1"
5+
"Settings": "0x8B9CbD3da94c637c0652c680Abd3CF7f787aBAF4"
66
}

deploy-addresses/optimism.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
2-
"Account": "0x3BC8D34314E77c2E36948Fd8F4B353f1baDc3F6C",
3-
"Events": "0x11193470df30B37Af9fc5Ec696c240D878bdfb42",
2+
"Account": "0x83E13069aA457778ca349E0128927B417A2c2B3f",
3+
"Events": "0xB753d2EE5dcA1fF39A83CA3Ec500656c31Be940b",
44
"Factory": "0x8234F990b149Ae59416dc260305E565e5DAfEb54",
5-
"Settings": "0xD02813baF080d06FC6F706cF93F5DaA96D6edB17"
5+
"Settings": "0x865dA103d126b3Be3599D84caB57109A861F5631"
66
}

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
{
22
"name": "@kwenta/cross-margin-manager",
3-
"version": "2.0.2",
3+
"version": "2.1.0",
44
"scripts": {
55
"compile": "forge build",
6-
"test": "forge test --fork-url $(grep ARCHIVE_NODE_URL_GOERLI_L2 .env | cut -d '=' -f2) --etherscan-api-key $(grep ETHERSCAN_API_KEY .env | cut -d '=' -f2) --gas-report -vvv",
6+
"test": "forge test --fork-url $(grep ARCHIVE_NODE_URL_L2 .env | cut -d '=' -f2) --etherscan-api-key $(grep ETHERSCAN_API_KEY .env | cut -d '=' -f2) --gas-report -vvv",
77
"format": "forge fmt",
8-
"coverage": "forge coverage --fork-url $(grep ARCHIVE_NODE_URL_GOERLI_L2 .env | cut -d '=' -f2)",
9-
"coverage:generate-lcov": "forge coverage --fork-url $(grep ARCHIVE_NODE_URL_GOERLI_L2 .env | cut -d '=' -f2) --report lcov",
8+
"coverage": "forge coverage --fork-url $(grep ARCHIVE_NODE_URL_L2 .env | cut -d '=' -f2)",
9+
"coverage:generate-lcov": "forge coverage --fork-url $(grep ARCHIVE_NODE_URL_L2 .env | cut -d '=' -f2) --report lcov",
1010
"check:upgradeability": "slither-check-upgradeability . Account --proxy-name AccountProxy",
1111
"analysis:solsat": "solstat --path ./src",
1212
"analysis:slither": "slither .",
13-
"gas-snapshot": "forge snapshot --fork-url $(grep ARCHIVE_NODE_URL_GOERLI_L2 .env | cut -d '=' -f2)",
13+
"gas-snapshot": "forge snapshot --fork-url $(grep ARCHIVE_NODE_URL_L2 .env | cut -d '=' -f2)",
1414
"view-storage-layout": "slither --print variable-order ."
1515
},
1616
"repository": {

script/Deploy.s.sol

Lines changed: 67 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,39 @@
11
// SPDX-License-Identifier: GPL-3.0-or-later
22
pragma solidity 0.8.18;
33

4-
import "forge-std/Script.sol";
5-
import "./utils/parameters/OptimismGoerliParameters.sol";
6-
import "./utils/parameters/OptimismParameters.sol";
4+
import {Script} from "lib/forge-std/src/Script.sol";
5+
6+
import {IAddressResolver} from "script/utils/interfaces/IAddressResolver.sol";
7+
78
import {Account} from "src/Account.sol";
89
import {Events} from "src/Events.sol";
910
import {Factory} from "src/Factory.sol";
10-
import {IAddressResolver} from "./utils/interfaces/IAddressResolver.sol";
11+
import {IAccount} from "src/interfaces/IAccount.sol";
1112
import {Settings} from "src/Settings.sol";
1213

14+
import {
15+
OPTIMISM_DEPLOYER,
16+
OPTIMISM_PDAO,
17+
OPTIMISM_SYNTHETIX_ADDRESS_RESOLVER,
18+
OPTIMISM_GELATO,
19+
OPTIMISM_OPS,
20+
OPTIMISM_UNISWAP_UNIVERSAL_ROUTER,
21+
OPTIMISM_UNISWAP_PERMIT2,
22+
PROXY_SUSD,
23+
PERPS_V2_EXCHANGE_RATE,
24+
FUTURES_MARKET_MANAGER,
25+
SYSTEM_STATUS
26+
} from "script/utils/parameters/OptimismParameters.sol";
27+
import {
28+
OPTIMISM_GOERLI_DEPLOYER,
29+
OPTIMISM_GOERLI_KWENTA_ADMIN_DAO_MULTI_SIG,
30+
OPTIMISM_GOERLI_SYNTHETIX_ADDRESS_RESOLVER,
31+
OPTIMISM_GOERLI_GELATO,
32+
OPTIMISM_GOERLI_OPS,
33+
OPTIMISM_GOERLI_UNISWAP_UNIVERSAL_ROUTER,
34+
OPTIMISM_GOERLI_UNISWAP_PERMIT2
35+
} from "script/utils/parameters/OptimismGoerliParameters.sol";
36+
1337
/// @title Script to deploy Kwenta's Smart Margin Account Factory
1438
/// @author JaredBorders ([email protected])
1539
contract Setup {
@@ -18,7 +42,9 @@ contract Setup {
1842
address _owner,
1943
address _addressResolver,
2044
address _gelato,
21-
address _ops
45+
address _ops,
46+
address _universalRouter,
47+
address _permit2
2248
)
2349
public
2450
returns (
@@ -28,40 +54,51 @@ contract Setup {
2854
Account implementation
2955
)
3056
{
57+
IAddressResolver addressResolver;
58+
3159
// define *initial* factory owner
3260
address temporaryOwner =
3361
_deployer == address(0) ? address(this) : _deployer;
3462

3563
// deploy the factory
3664
factory = new Factory({
37-
_owner: temporaryOwner
38-
});
65+
_owner: temporaryOwner
66+
});
3967

4068
// deploy the events contract and set the factory
4169
events = new Events({
42-
_factory: address(factory)
43-
});
70+
_factory: address(factory)
71+
});
4472

4573
// deploy the settings contract
4674
settings = new Settings({
47-
_owner: _owner
48-
});
75+
_owner: _owner
76+
});
4977

5078
// resolve necessary addresses via the Synthetix Address Resolver
51-
IAddressResolver addressResolver = IAddressResolver(_addressResolver);
52-
53-
implementation = new Account({
54-
_factory: address(factory),
55-
_events: address(events),
56-
_marginAsset: addressResolver.getAddress({name: PROXY_SUSD}),
57-
_perpsV2ExchangeRate: addressResolver.getAddress({name: PERPS_V2_EXCHANGE_RATE}),
58-
_futuresMarketManager: addressResolver.getAddress({name: FUTURES_MARKET_MANAGER}),
59-
_systemStatus: addressResolver.getAddress({name: SYSTEM_STATUS}),
60-
_gelato: _gelato,
61-
_ops: _ops,
62-
_settings: address(settings)
79+
addressResolver = IAddressResolver(_addressResolver);
80+
81+
IAccount.AccountConstructorParams memory params = IAccount
82+
.AccountConstructorParams({
83+
factory: address(factory),
84+
events: address(events),
85+
marginAsset: addressResolver.getAddress({name: PROXY_SUSD}),
86+
perpsV2ExchangeRate: addressResolver.getAddress({
87+
name: PERPS_V2_EXCHANGE_RATE
88+
}),
89+
futuresMarketManager: addressResolver.getAddress({
90+
name: FUTURES_MARKET_MANAGER
91+
}),
92+
systemStatus: addressResolver.getAddress({name: SYSTEM_STATUS}),
93+
gelato: _gelato,
94+
ops: _ops,
95+
settings: address(settings),
96+
universalRouter: _universalRouter,
97+
permit2: _permit2
6398
});
6499

100+
implementation = new Account(params);
101+
65102
// update the factory with the new account implementation
66103
factory.upgradeAccountImplementation({
67104
_implementation: address(implementation)
@@ -82,10 +119,12 @@ contract DeployOptimism is Script, Setup {
82119

83120
Setup.deploySystem({
84121
_deployer: OPTIMISM_DEPLOYER,
85-
_owner: OPTIMISM_KWENTA_ADMIN_DAO_MULTI_SIG,
122+
_owner: OPTIMISM_PDAO,
86123
_addressResolver: OPTIMISM_SYNTHETIX_ADDRESS_RESOLVER,
87124
_gelato: OPTIMISM_GELATO,
88-
_ops: OPTIMISM_OPS
125+
_ops: OPTIMISM_OPS,
126+
_universalRouter: OPTIMISM_UNISWAP_UNIVERSAL_ROUTER,
127+
_permit2: OPTIMISM_UNISWAP_PERMIT2
89128
});
90129

91130
vm.stopBroadcast();
@@ -105,7 +144,9 @@ contract DeployOptimismGoerli is Script, Setup {
105144
_owner: OPTIMISM_GOERLI_KWENTA_ADMIN_DAO_MULTI_SIG,
106145
_addressResolver: OPTIMISM_GOERLI_SYNTHETIX_ADDRESS_RESOLVER,
107146
_gelato: OPTIMISM_GOERLI_GELATO,
108-
_ops: OPTIMISM_GOERLI_OPS
147+
_ops: OPTIMISM_GOERLI_OPS,
148+
_universalRouter: OPTIMISM_GOERLI_UNISWAP_UNIVERSAL_ROUTER,
149+
_permit2: OPTIMISM_GOERLI_UNISWAP_PERMIT2
109150
});
110151

111152
vm.stopBroadcast();

0 commit comments

Comments
 (0)