Skip to content

Commit

Permalink
Scripts to deploy smart escrow and transfer tokens
Browse files Browse the repository at this point in the history
  • Loading branch information
anikaraghu committed Feb 23, 2024
1 parent adb217c commit b03b25a
Show file tree
Hide file tree
Showing 6 changed files with 236 additions and 0 deletions.
23 changes: 23 additions & 0 deletions mainnet/2024-02-21-setup-smart-escrow/.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
OPTIMISM_RPC_URL=

OP_COMMIT=3580bf1b41d80fcb2b895d5610836bfad27fc989
BASE_CONTRACTS_COMMIT=3a566fcc0e01535cf93dbcef6704640cbde222aa

OP_TOKEN=0x4200000000000000000000000000000000000042

DEPLOYER=0xbebe472f467888b197b90693b8852ad12a50b261
BENEFACTOR=XXX
BENEFICIARY=0x07114fF6F815113729b579B4A233192BAEF0e0E18
BENEFACTOR_OWNER=0x2501c477D0A35545a387Aa4A3EEe4292A9a8B3F0
BENEFICIARY_OWNER=0x6e1DFd5C1E22A4677663A81D24C6BA03561ef0f6
NESTED_SAFE=0x0a7361e734cf3f0394B0FC4a45C74E7a4Ec70940
START=1720674000
END=1870572600
VESTING_PERIOD_SECONDS=7889400
INITIAL_TOKENS=17895697
VESTING_EVENT_TOKENS=4473924

SMART_ESCROW_CONTRACT=TODO
COLLAB_GRANT_TOKENS=107374177
UPFRONT_GRANT_TOKENS=10737418
CB_GOVERNANCE_WALLET=
30 changes: 30 additions & 0 deletions mainnet/2024-02-21-setup-smart-escrow/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
include ../../Makefile
include ../.env
include .env

.PHONY: deploy-new-implementations
deploy-new-implementations:
forge script --rpc-url $(OPTIMISM_RPC_URL) DeploySmartEscrow



##
# TODO: fill in the following commands for the transfer token task
##

.PHONY: sign
sign:
$(GOPATH)/bin/eip712sign --ledger --hd-paths "m/44'/60'/$(LEDGER_ACCOUNT)'/0/0" -- \
forge script --rpc-url $(OPTIMISM_RPC_URL) TransferOPTokens \
--sig "sign(address)" $(SIGNER_SAFE_ADDR)

.PHONY: approve
approve:
forge script --rpc-url $(OPTIMISM_RPC_URL) TransferOPTokens \
--sig "approve(address,bytes)" $(SIGNER_SAFE_ADDR) $(SIGNATURES) \
--ledger --hd-paths "m/44'/60'/$(LEDGER_ACCOUNT)'/0/0"

.PHONY: execute
execute:
forge script --rpc-url $(OPTIMISM_RPC_URL) TransferOPTokens \
--sig "run()" --ledger --hd-paths "m/44'/60'/$(LEDGER_ACCOUNT)'/0/0"
19 changes: 19 additions & 0 deletions mainnet/2024-02-21-setup-smart-escrow/foundry.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
[profile.default]
src = 'src'
out = 'out'
libs = ['lib']
broadcast = 'records'
fs_permissions = [ {access = "read-write", path = "./"} ]
optimizer = true
optimizer_runs = 999999
solc_version = "0.8.15"
via-ir = true
remappings = [
'@eth-optimism-bedrock/=lib/optimism/packages/contracts-bedrock/',
'@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts',
'@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts',
'@rari-capital/solmate/=lib/solmate/',
'@base-contracts/=lib/base-contracts'
]

# See more config options https://github.com/foundry-rs/foundry/tree/master/config
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;

import "forge-std/Script.sol";
import "@base-contracts/src/smart-escrow/SmartEscrow.sol";

contract DeploySmartEscrow is Script {
address internal DEPLOYER = vm.envAddress("DEPLOYER");
address internal BENEFACTOR = vm.envAddress("BENEFACTOR");
address internal BENEFICIARY = vm.envAddress("BENEFICIARY");
address internal BENEFACTOR_OWNER = vm.envAddress("BENEFACTOR_OWNER");
address internal BENEFICIARY_OWNER = vm.envAddress("BENEFICIARY_OWNER");
address internal ESCROW_OWNER = vm.envAddress("NESTED_SAFE");
uint256 internal START = vm.envUint256("START");
uint256 internal END = vm.envUint256("END");
uint256 internal VESTING_PERIOD_SECONDS = vm.envUint256("VESTING_PERIOD_SECONDS");
uint256 internal INITIAL_TOKENS = vm.envUint256("INITIAL_TOKENS");
uint256 internal VESTING_EVENT_TOKENS = vm.envUint256("VESTING_EVENT_TOKENS");

function run() public {
vm.broadcast(deployer);
SmartEscrow smartEscrow = new SmartEscrow(
BENEFACTOR,
BENEFICIARY,
BENEFACTOR_OWNER,
BENEFICIARY_OWNER,
ESCROW_OWNER,
START,
END,
VESTING_PERIOD_SECONDS,
INITIAL_TOKENS,
VESTING_EVENT_TOKENS
);
require(smartEscrow.start() = START);
require(smartEscrow.end() = END);
require(smartEscrow.vestingPeriod() = VESTING_PERIOD_SECONDS);
require(smartEscrow.initialTokens() = INITIAL_TOKENS);
require(smartEscrow.vestingEventTokens() = VESTING_EVENT_TOKENS);
require(smartEscrow.benefactor() = BENEFATOR);
require(smartEscrow.beneficiary() = BENEFICIARY);
require(smartEscrow.released() = 0);
require(smartEscrow.contractTerminated() = false);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;

import "@base-contracts/script/universal/NestedMultisigBuilder.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Votes.sol";
import "@agora/structs/RulesV3.sol";
import "@agora/structs/AllowanceType.sol";
import "@agora/alligator/AlligatorOP_V5.sol";

contract TransferOPTokens is NestedMultisigBuilder {
using SafeERC20 for IERC20;
using ERC20Votes for IERC20;

address constant internal NESTED_SAFE = vm.envAddress("NESTED_SAFE");
IERC20 public constant OP_TOKEN = IERC20(vm.envAddress("OP_TOKEN"));
address public constant SMART_ESCROW = vm.envAddress("SMART_ESCROW_CONTRACT");
address public constant ALLIGATOR_PROXY = vm.envAddress("ALLIGATOR_PROXY"); // Agora address which will allow for subdeletation
address public constant CB_GOVERNANCE_WALLET = vm.envAddress("CB_GOVERNANCE_WALLET");

uint256 public constant COLLAB_GRANT_TOKENS = vm.envUint256("COLLAB_GRANT_TOKENS");
uint256 public constant UPFRONT_GRANT_TOKENS = vm.envUint256("UPFRONT_GRANT_TOKENS");

function _postCheck() internal override view {
// TODO
}

function _buildCalls() internal override view returns (IMulticall3.Call3[] memory) {
IMulticall3.Call3[] memory calls = new IMulticall3.Call3[](3);

// Transfer collaboration grant tokens to smart escrow
calls[0] = IMulticall3.Call3({
target: OP_TOKEN,
allowFailure: false,
callData: abi.encodeCall(
token.safeTransferFrom(address, address, uint256);
NESTED_SAFE,
SMART_ESCROW,
COLLAB_GRANT_TOKENS
)
});
// Delegate governance tokens for initial grant to Agora's Alligator proxy, which will allow for subdelegations
calls[1] = IMulticall3.Call3({
target: OP_TOKEN,
allowFailure: false,
callData: abi.encodeCall(
delegate(address),
ALLIGATOR_PROXY
)
});

SubdelegationRules subdelegationRules = SubdelegationRules({
maxRedelegations: 2,
blocksBeforeVoteCloses: 0,
notValidBefore: 0,
notValidAfter: 0,
customRule: address(0),
allowanceType: AllowanceType.Absolute,
allowance: 1e18
});

// Delegate the tokens to the Coinbase owned address
calls[2] = IMulticall3.Call3({
target: ALLIGATOR_PROXY,
allowFailure: false,
callData: abi.encodeCall(
subdelegate(address, SubdelegationRules),
CB_GOVERNANCE_WALLET,
subdelegationRules
)
});

return calls;
}

function _ownerSafe() internal override view returns (address) {
return NESTED_SAFE;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.15;

import "@base-contracts/script/universal/NestedMultisigBuilder.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";

// TODO: this script will be called after the upfront grant tokens have vested
contract TransferOPTokens is NestedMultisigBuilder {
using SafeERC20 for IERC20;

address constant internal NESTED_SAFE = vm.envAddress("NESTED_SAFE");
IERC20 public constant OP_TOKEN = IERC20(vm.envAddress("OP_TOKEN"));
address public constant BENEFICIARY = vm.envAddress("BENEFICIARY");
uint256 public constant UPFRONT_GRANT_TOKENS = vm.envUint256("UPFRONT_GRANT_TOKENS");

function _postCheck() internal override view {
// TODO
}

function _buildCalls() internal override view returns (IMulticall3.Call3[] memory) {
IMulticall3.Call3[] memory calls = new IMulticall3.Call3[](1);

// Transfer upfront grant tokens when they vest
calls[0] = IMulticall3.Call3({
target: OP_TOKEN,
allowFailure: false,
callData: abi.encodeCall(
token.safeTransferFrom(address, address, uint256);
NESTED_SAFE,
BENEFICIARY,
UPFRONT_GRANT_TOKENS // or maybe just the whole balance?
)
});

return calls;
}

function _ownerSafe() internal override view returns (address) {
return NESTED_SAFE;
}
}

0 comments on commit b03b25a

Please sign in to comment.