Skip to content

Commit

Permalink
📣 Add Delegate Events
Browse files Browse the repository at this point in the history
  • Loading branch information
JaredBorders authored Oct 25, 2023
2 parents 9eac8a7 + a935ebe commit 44ba404
Show file tree
Hide file tree
Showing 19 changed files with 956 additions and 201 deletions.
293 changes: 151 additions & 142 deletions .gas-snapshot

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions deploy-addresses/optimism-goerli.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"Account": "0x5f78a5EdF0B356F50886a6829Fc02B16532e8735",
"Events": "0xe32F27B27F4ea5f10f269b52223910bA83e2933C",
"Account": "0x62b26650A52E1B6a669C21a9d43aFD78AC0Ef84F",
"Events": "0x4533D9eAC2eb200B98fD9BaA306221ad2528e52F",
"Factory": "0x30582eeE34719fe22b1B6c3b607636A3ab94522E",
"Settings": "0x8B9CbD3da94c637c0652c680Abd3CF7f787aBAF4"
}
4 changes: 2 additions & 2 deletions deploy-addresses/optimism.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"Account": "0x6B86c1A6878940666489780871E1C98B366d0aFF",
"Events": "0xB753d2EE5dcA1fF39A83CA3Ec500656c31Be940b",
"Account": "0x9AcbDBABafC7E47dE0769C352b725Fa9fd443Bc2",
"Events": "0x349142D51afCFbB3E9ef70DB1F7dB8437aABC5F7",
"Factory": "0x8234F990b149Ae59416dc260305E565e5DAfEb54",
"Settings": "0x865dA103d126b3Be3599D84caB57109A861F5631"
}
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@kwenta/cross-margin-manager",
"version": "2.1.1",
"version": "2.1.2",
"scripts": {
"compile": "forge build",
"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",
Expand Down
136 changes: 136 additions & 0 deletions script/upgrades/v2.1.2/Upgrade.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity 0.8.18;

import {Script} from "lib/forge-std/src/Script.sol";

import {IAddressResolver} from "script/utils/interfaces/IAddressResolver.sol";

import {Account} from "src/Account.sol";
import {Events} from "src/Events.sol";
import {Settings} from "src/Settings.sol";
import {IAccount} from "src/interfaces/IAccount.sol";

import {
OPTIMISM_PDAO,
OPTIMISM_GELATO,
OPTIMISM_OPS,
FUTURES_MARKET_MANAGER,
OPTIMISM_FACTORY,
OPTIMISM_EVENTS,
OPTIMISM_SETTINGS,
OPTIMISM_SYNTHETIX_ADDRESS_RESOLVER,
OPTIMISM_UNISWAP_PERMIT2,
OPTIMISM_UNISWAP_UNIVERSAL_ROUTER,
PERPS_V2_EXCHANGE_RATE,
PROXY_SUSD,
SYSTEM_STATUS
} from "script/utils/parameters/OptimismParameters.sol";
import {
OPTIMISM_GOERLI_DEPLOYER,
OPTIMISM_GOERLI_EVENTS,
OPTIMISM_GOERLI_SETTINGS,
OPTIMISM_GOERLI_FACTORY,
OPTIMISM_GOERLI_GELATO,
OPTIMISM_GOERLI_OPS,
OPTIMISM_GOERLI_SYNTHETIX_ADDRESS_RESOLVER,
OPTIMISM_GOERLI_UNISWAP_PERMIT2,
OPTIMISM_GOERLI_UNISWAP_UNIVERSAL_ROUTER
} from "script/utils/parameters/OptimismGoerliParameters.sol";

/// @title Script to upgrade the Account implementation v2.1.1 -> v2.1.2
/// @author JaredBorders ([email protected])

/// @dev steps to deploy and verify on Optimism:
/// (1) load the variables in the .env file via `source .env`
/// (2) run `forge script script/upgrades/v2.1.2/Upgrade.s.sol:UpgradeAccountOptimism --rpc-url $ARCHIVE_NODE_URL_L2 --broadcast --verify -vvvv`
/// (3) Smart Margin Account Factory owner (i.e. Kwenta pDAO) will need to call `upgradeAccountImplementation` on the Factory with the address of the new Account implementation
contract UpgradeAccountOptimism is Script {
function run() public {
uint256 deployerPrivateKey = vm.envUint("DEPLOYER_PRIVATE_KEY");
vm.startBroadcast(deployerPrivateKey);

upgrade();

vm.stopBroadcast();
}

function upgrade() public returns (address implementation) {
IAddressResolver addressResolver =
IAddressResolver(OPTIMISM_SYNTHETIX_ADDRESS_RESOLVER);

// deploy events
address events = address(new Events({_factory: OPTIMISM_FACTORY}));

address marginAsset = addressResolver.getAddress({name: PROXY_SUSD});
address perpsV2ExchangeRate =
addressResolver.getAddress({name: PERPS_V2_EXCHANGE_RATE});
address futuresMarketManager =
addressResolver.getAddress({name: FUTURES_MARKET_MANAGER});
address systemStatus = addressResolver.getAddress({name: SYSTEM_STATUS});

IAccount.AccountConstructorParams memory params = IAccount
.AccountConstructorParams({
factory: OPTIMISM_FACTORY,
events: events,
marginAsset: marginAsset,
perpsV2ExchangeRate: perpsV2ExchangeRate,
futuresMarketManager: futuresMarketManager,
systemStatus: systemStatus,
gelato: OPTIMISM_GELATO,
ops: OPTIMISM_OPS,
settings: OPTIMISM_SETTINGS,
universalRouter: OPTIMISM_UNISWAP_UNIVERSAL_ROUTER,
permit2: OPTIMISM_UNISWAP_PERMIT2
});

implementation = address(new Account(params));
}
}

/// @dev steps to deploy and verify on Optimism Goerli:
/// (1) load the variables in the .env file via `source .env`
/// (2) run `forge script script/upgrades/v2.1.2/Upgrade.s.sol:UpgradeAccountOptimismGoerli --rpc-url $ARCHIVE_NODE_URL_GOERLI_L2 --broadcast --verify -vvvv`
/// (3) Smart Margin Account Factory owner (i.e. Kwenta pDAO) will need to call `upgradeAccountImplementation` on the Factory with the address of the new Account implementation
contract UpgradeAccountOptimismGoerli is Script {
function run() public {
uint256 deployerPrivateKey = vm.envUint("DEPLOYER_PRIVATE_KEY");
vm.startBroadcast(deployerPrivateKey);

upgrade();

vm.stopBroadcast();
}

function upgrade() public returns (address implementation) {
IAddressResolver addressResolver =
IAddressResolver(OPTIMISM_GOERLI_SYNTHETIX_ADDRESS_RESOLVER);

// deploy events
address events =
address(new Events({_factory: OPTIMISM_GOERLI_FACTORY}));

address marginAsset = addressResolver.getAddress({name: PROXY_SUSD});
address perpsV2ExchangeRate =
addressResolver.getAddress({name: PERPS_V2_EXCHANGE_RATE});
address futuresMarketManager =
addressResolver.getAddress({name: FUTURES_MARKET_MANAGER});
address systemStatus = addressResolver.getAddress({name: SYSTEM_STATUS});

IAccount.AccountConstructorParams memory params = IAccount
.AccountConstructorParams({
factory: OPTIMISM_GOERLI_FACTORY,
events: events,
marginAsset: marginAsset,
perpsV2ExchangeRate: perpsV2ExchangeRate,
futuresMarketManager: futuresMarketManager,
systemStatus: systemStatus,
gelato: OPTIMISM_GOERLI_GELATO,
ops: OPTIMISM_GOERLI_OPS,
settings: OPTIMISM_GOERLI_SETTINGS,
universalRouter: OPTIMISM_GOERLI_UNISWAP_UNIVERSAL_ROUTER,
permit2: OPTIMISM_GOERLI_UNISWAP_PERMIT2
});

implementation = address(new Account(params));
}
}
10 changes: 5 additions & 5 deletions script/utils/parameters/OptimismGoerliParameters.sol
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,15 @@ address constant OPTIMISM_GOERLI_GELATO =
address constant OPTIMISM_GOERLI_OPS =
0x255F82563b5973264e89526345EcEa766DB3baB2;

// v2.1.1
// v2.1.2
address constant OPTIMISM_GOERLI_IMPLEMENTATION =
0x5f78a5EdF0B356F50886a6829Fc02B16532e8735;
0x62b26650A52E1B6a669C21a9d43aFD78AC0Ef84F;

// released with v2.1.0 implementation (used by v2.1.*)
// released with v2.1.2 implementation (used by v2.1.*)
address constant OPTIMISM_GOERLI_EVENTS =
0xe32F27B27F4ea5f10f269b52223910bA83e2933C;
0x4533D9eAC2eb200B98fD9BaA306221ad2528e52F;

// updated with v2.1.1 implementation
// updated with v2.1.2 implementation
address constant OPTIMISM_GOERLI_FACTORY =
0x30582eeE34719fe22b1B6c3b607636A3ab94522E;

Expand Down
10 changes: 5 additions & 5 deletions script/utils/parameters/OptimismParameters.sol
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,14 @@ address constant OPTIMISM_GELATO = 0x01051113D81D7d6DA508462F2ad6d7fD96cF42Ef;

address constant OPTIMISM_OPS = 0x340759c8346A1E6Ed92035FB8B6ec57cE1D82c2c;

// v2.1.1
// v2.1.2
address constant OPTIMISM_IMPLEMENTATION =
0x6B86c1A6878940666489780871E1C98B366d0aFF;
0x9AcbDBABafC7E47dE0769C352b725Fa9fd443Bc2;

// released with v2.1.0 implementation (used by v2.1.*)
address constant OPTIMISM_EVENTS = 0xB753d2EE5dcA1fF39A83CA3Ec500656c31Be940b;
// released with v2.1.2 implementation (used by v2.1.*)
address constant OPTIMISM_EVENTS = 0x349142D51afCFbB3E9ef70DB1F7dB8437aABC5F7;

// updated with v2.1.1 implementation
// updated with v2.1.2 implementation
address constant OPTIMISM_FACTORY = 0x8234F990b149Ae59416dc260305E565e5DAfEb54;

// released with v2.1.0 implementation (used by v2.1.*)
Expand Down
43 changes: 38 additions & 5 deletions src/Account.sol
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ contract Account is IAccount, Auth, OpsReady {
//////////////////////////////////////////////////////////////*/

/// @inheritdoc IAccount
bytes32 public constant VERSION = "2.1.1";
bytes32 public constant VERSION = "2.1.2";

/// @notice tracking code used when modifying positions
bytes32 internal constant TRACKING_CODE = "KWENTA";
Expand Down Expand Up @@ -218,13 +218,14 @@ contract Account is IAccount, Auth, OpsReady {
/// @inheritdoc IAccount
function setInitialOwnership(address _owner) external override {
if (msg.sender != address(FACTORY)) revert Unauthorized();

/// @dev set owner directly
owner = _owner;
emit OwnershipTransferred(address(0), _owner);

EVENTS.emitOwnershipTransferred({caller: address(0), newOwner: _owner});
}

/// @notice transfer ownership of account to new address
/// @dev update factory's record of account ownership
/// @param _newOwner: new account owner
/// @inheritdoc Auth
function transferOwnership(address _newOwner) public override {
// will revert if msg.sender is *NOT* owner
super.transferOwnership(_newOwner);
Expand All @@ -234,6 +235,38 @@ contract Account is IAccount, Auth, OpsReady {
_newOwner: _newOwner,
_oldOwner: msg.sender // verified to be old owner
});

/// @notice previous owner was verified to be msg.sender
EVENTS.emitOwnershipTransferred({
caller: msg.sender,
newOwner: _newOwner
});
}

/*//////////////////////////////////////////////////////////////
DELEGATION
//////////////////////////////////////////////////////////////*/

/// @inheritdoc Auth
function addDelegate(address _delegate) public override {
// will revert if msg.sender is *NOT* owner
super.addDelegate(_delegate);

EVENTS.emitDelegatedAccountAdded({
caller: msg.sender,
delegate: _delegate
});
}

/// @inheritdoc Auth
function removeDelegate(address _delegate) public override {
// will revert if msg.sender is *NOT* owner
super.removeDelegate(_delegate);

EVENTS.emitDelegatedAccountRemoved({
caller: msg.sender,
delegate: _delegate
});
}

/*//////////////////////////////////////////////////////////////
Expand Down
27 changes: 27 additions & 0 deletions src/Events.sol
Original file line number Diff line number Diff line change
Expand Up @@ -143,4 +143,31 @@ contract Events is IEvents {
priceOracle: priceOracle
});
}

/// @inheritdoc IEvents
function emitOwnershipTransferred(address caller, address newOwner)
external
override
onlyAccounts
{
emit OwnershipTransferred({caller: caller, newOwner: newOwner});
}

/// @inheritdoc IEvents
function emitDelegatedAccountAdded(address caller, address delegate)
external
override
onlyAccounts
{
emit DelegatedAccountAdded({caller: caller, delegate: delegate});
}

/// @inheritdoc IEvents
function emitDelegatedAccountRemoved(address caller, address delegate)
external
override
onlyAccounts
{
emit DelegatedAccountRemoved({caller: caller, delegate: delegate});
}
}
2 changes: 1 addition & 1 deletion src/interfaces/IAccount.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ pragma solidity 0.8.18;
import {IPerpsV2MarketConsolidated} from
"src/interfaces/synthetix/IPerpsV2MarketConsolidated.sol";

/// @title Kwenta Smart Margin Account v2.1.1 Implementation Interface
/// @title Kwenta Smart Margin Account v2.1.2 Implementation Interface
/// @author JaredBorders ([email protected]), JChiaramonte7 ([email protected])
interface IAccount {
/*///////////////////////////////////////////////////////////////
Expand Down
30 changes: 30 additions & 0 deletions src/interfaces/IEvents.sol
Original file line number Diff line number Diff line change
Expand Up @@ -147,4 +147,34 @@ interface IEvents {
uint256 keeperFee,
IAccount.PriceOracleUsed priceOracle
);

/// @notice emitted after ownership transfer
/// @param caller: previous owner
/// @param newOwner: new owner
function emitOwnershipTransferred(address caller, address newOwner)
external;

event OwnershipTransferred(
address indexed caller, address indexed newOwner
);

/// @notice emitted after a delegate is added
/// @param caller: owner of the account
/// @param delegate: address of the delegate being added
function emitDelegatedAccountAdded(address caller, address delegate)
external;

event DelegatedAccountAdded(
address indexed caller, address indexed delegate
);

/// @notice emitted after a delegate is removed
/// @param caller: owner of the account
/// @param delegate: address of the delegate being removed
function emitDelegatedAccountRemoved(address caller, address delegate)
external;

event DelegatedAccountRemoved(
address indexed caller, address indexed delegate
);
}
Loading

0 comments on commit 44ba404

Please sign in to comment.