Skip to content

Commit

Permalink
updated payload
Browse files Browse the repository at this point in the history
  • Loading branch information
achab committed Mar 31, 2023
1 parent 1467bd3 commit f0d201e
Show file tree
Hide file tree
Showing 7 changed files with 168 additions and 114 deletions.
114 changes: 7 additions & 107 deletions contracts/l1/AaveStarknetBridgeUpgradePayload.sol
Original file line number Diff line number Diff line change
@@ -1,126 +1,26 @@
// SPDX-License-Identifier: Apache-2.0.
pragma solidity ^0.8.0;

import {AaveGovernanceV2} from "@bgd-labs/aave-address-book/src/AaveGovernanceV2.sol";
import {ITransparentProxyFactory} from "./interfaces/IProxyFactory.sol";
import {IBridge} from "./interfaces/IBridge.sol";
import {ICrosschainForwarderStarknet} from "./interfaces/ICrosschainForwarderStarknet.sol";
import {ITransparentUpgradeableProxy} from "./interfaces/IProxy.sol";

/**
* @title AaveStarknetBridgeUpgradePayload
* @author Aave on Starknet
* @notice Aave governance proposal payload, upgrading the Aave <> Starknet Aave v2 Ethereum Bridge on Ethereum side
*/
contract AaveStarknetBridgeUpgradePayload {
address public constant STARKNET_MESSAGING_CORE =
0xc662c410C0ECf747543f5bA90660f6ABeBD9C8c4;
ICrosschainForwarderStarknet public constant CROSSCHAIN_FORWARDER_STARKNET =
ICrosschainForwarderStarknet(
0x8c598667A5a6A14F04172326e62CE143BF8edaAB
address public constant L1_BRIDGE_NEW_IMPLEMENTATION_ADDRESS = address(0);
ITransparentUpgradeableProxy public constant L1_BRIDGE_PROXY =
ITransparentUpgradeableProxy(
0x25c0667E46a704AfCF5305B0A586CC24c171E94D
);
uint256 public constant L2_BRIDGE =
0x0434ab0e4f2a743f871e4d57a16aef3df84c1a29b61565e016da91c1f824b021;
address public constant INCENTIVES_CONTROLLER =
0xd784927Ff2f95ba542BfC824c8a8a98F3495f6b5;
ITransparentProxyFactory public constant PROXY_FACTORY =
ITransparentProxyFactory(0xC354ce29aa85e864e55277eF47Fc6a92532Dd6Ca);
string public constant ID_L1_BRIDGE = "aave_v2_ethereum.starknet_bridge";

IBridge public constant L1_BRIDGE_IMPLEMENTATION =
IBridge(0x69F4057cC8A32bdE63c2d62724CE14Ed1aD4B93A);
uint256 public constant L2_INIT_SPELL =
0x00be3e7fe64939ef463bc80b76703b93c10a61944de34df5bb2dbc7b734e3159;

function execute() external {
(
address[] memory l1Tokens,
uint256[] memory l2Tokens,
uint256[] memory ceilings
) = getTokensData();

try
/// @dev Using createDeterministic() because the spell on L2 side needs to know in advance the address
/// of the proxy to be deployed
PROXY_FACTORY.createDeterministic(
address(L1_BRIDGE_IMPLEMENTATION),
AaveGovernanceV2.SHORT_EXECUTOR,
abi.encodeWithSelector(
L1_BRIDGE_IMPLEMENTATION.initialize.selector,
L2_BRIDGE,
STARKNET_MESSAGING_CORE,
INCENTIVES_CONTROLLER,
l1Tokens,
l2Tokens,
ceilings
),
keccak256(abi.encode(ID_L1_BRIDGE))
)
L1_BRIDGE_PROXY.upgradeTo(L1_BRIDGE_NEW_IMPLEMENTATION_ADDRESS)
{} catch (bytes memory) {
// Do nothing. If reverted, it is because the contract is already deployed
// and initialized with exactly the parameters we require
// Do nothing.
}

// Send message to activate the L2 side of the system, by nested delegatecall to the forwarder
(bool success, ) = address(CROSSCHAIN_FORWARDER_STARKNET).delegatecall(
abi.encodeWithSelector(
CROSSCHAIN_FORWARDER_STARKNET.execute.selector,
L2_INIT_SPELL
)
);

require(success, "CROSSCHAIN_FORWARDER_STARKNET_execute()");
}

function predictProxyAddress() public view returns (address) {
(
address[] memory l1Tokens,
uint256[] memory l2Tokens,
uint256[] memory ceilings
) = getTokensData();

return
PROXY_FACTORY.predictCreateDeterministic(
address(L1_BRIDGE_IMPLEMENTATION),
AaveGovernanceV2.SHORT_EXECUTOR,
abi.encodeWithSelector(
L1_BRIDGE_IMPLEMENTATION.initialize.selector,
L2_BRIDGE,
STARKNET_MESSAGING_CORE,
INCENTIVES_CONTROLLER,
l1Tokens,
l2Tokens,
ceilings
),
keccak256(abi.encode(ID_L1_BRIDGE))
);
}

function getTokensData()
public
pure
returns (address[] memory, uint256[] memory, uint256[] memory)
{
address[] memory l1Tokens = new address[](3);
l1Tokens[0] = 0xBcca60bB61934080951369a648Fb03DF4F96263C; // aUSDC
l1Tokens[1] = 0x3Ed3B47Dd13EC9a98b44e6204A523E766B225811; // aUSDT
l1Tokens[2] = 0x028171bCA77440897B824Ca71D1c56caC55b68A3; // aDAI

uint256[] memory l2Tokens = new uint256[](3);
l2Tokens[
0
] = 0x014cdaa224881ea760b055a50b7b8e65447d9310f5c637294e08a0fc0d04c0ce; // static aUSDC
l2Tokens[
1
] = 0x02e905e3d2fcf4e5813fef9bfe528a304e8e5adc8cbdc247b3980d7a96a01b90; // static aUSDT
l2Tokens[
2
] = 0x04212f12efcfc9e847bd98e58daff7dc588c4896f6cd320b74023ad5606f02fd; // static aDAI

uint256[] memory ceilings = new uint256[](3);
ceilings[0] = 30_000_000000; // ceiling of aUSDC, 6 decimals
ceilings[1] = 30_000_000000; // ceiling of aUSDT, 6 decimals
ceilings[2] = 30_000 ether; // ceiling of aDAI, 18 decimals

return (l1Tokens, l2Tokens, ceilings);
}
}
11 changes: 6 additions & 5 deletions contracts/l1/Bridge.sol
Original file line number Diff line number Diff line change
Expand Up @@ -123,8 +123,7 @@ contract Bridge is IBridge, Initializable {
address(underlyingAsset),
lendingPool
);
uint256 l2MsgNonce = _messagingContract.l1ToL2MessageNonce();
_sendDepositMessage(
uint256 l2MsgNonce = _sendDepositMessage(
l1AToken,
msg.sender,
l2Recipient,
Expand Down Expand Up @@ -154,7 +153,7 @@ contract Bridge is IBridge, Initializable {
uint256 staticAmount,
uint256 l2RewardsIndex,
bool toUnderlyingAsset
) external override {
) external payable override {
require(recipient != address(0), Errors.B_INVALID_ADDRESS);
require(staticAmount > 0, Errors.B_INSUFFICIENT_AMOUNT);

Expand Down Expand Up @@ -313,7 +312,7 @@ contract Bridge is IBridge, Initializable {
uint256 blockNumber,
uint256 currentRewardsIndex,
uint256 fee
) internal {
) internal returns (uint256) {
uint256[] memory payload = new uint256[](9);
payload[0] = uint256(uint160(from));
payload[1] = l2Recipient;
Expand All @@ -322,11 +321,13 @@ contract Bridge is IBridge, Initializable {
(payload[5], payload[6]) = Cairo.toSplitUint(blockNumber);
(payload[7], payload[8]) = Cairo.toSplitUint(currentRewardsIndex);

_messagingContract.sendMessageToL2{value: fee}(
uint256 nonce;
(, nonce) = _messagingContract.sendMessageToL2{value: fee}(
_l2Bridge,
Cairo.DEPOSIT_HANDLER,
payload
);
return nonce;
}

function _sendIndexUpdateMessage(
Expand Down
2 changes: 1 addition & 1 deletion contracts/l1/governance/CrosschainForwarderStarknet.sol
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ contract CrosschainForwarderStarknet {
l2GovernanceRelay = _l2GovernanceRelay;
}

function execute(uint256 spell) public payable {
function execute(uint256 spell) external payable {
uint256[] memory payload = new uint256[](1);
payload[0] = spell;
StarkNetLike(starkNet).sendMessageToL2{value: msg.value}(
Expand Down
2 changes: 1 addition & 1 deletion contracts/l1/interfaces/ICrosschainForwarderStarknet.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@
pragma solidity ^0.8.0;

interface ICrosschainForwarderStarknet {
function execute(uint256 spell) external;
function execute(uint256 spell) external payable;
}
57 changes: 57 additions & 0 deletions contracts/l1/interfaces/IProxy.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

interface ITransparentUpgradeableProxy {
/**
* @dev Returns the current admin.
*
* NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.
*
* TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the
* https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.
* `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`
*/
function admin() external payable returns (address admin_);

/**
* @dev Returns the current implementation.
*
* NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.
*
* TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the
* https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.
* `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`
*/
function implementation()
external
payable
returns (address implementation_);

/**
* @dev Changes the admin of the proxy.
*
* Emits an {AdminChanged} event.
*
* NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.
*/
function changeAdmin(address newAdmin) external payable;

/**
* @dev Upgrade the implementation of the proxy.
*
* NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.
*/
function upgradeTo(address newImplementation) external payable;

/**
* @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified
* by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the
* proxied contract.
*
* NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.
*/
function upgradeToAndCall(
address newImplementation,
bytes calldata data
) external payable;
}
34 changes: 34 additions & 0 deletions scripts/deployBridge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,40 @@ export async function deployL1Bridge(
}
}

export async function deployL1BridgeImplementation(signer: SignerWithAddress) {
let bridgeFactory: ContractFactory;
let bridgeImpl: Contract;

try {
console.log("Deploying L1 bridge implementation...");

bridgeFactory = await ethers.getContractFactory("Bridge", signer);
bridgeImpl = await bridgeFactory.deploy();
await bridgeImpl.deployed();

console.log(
"L1 bridge implementation contract is deployed at address: ",
bridgeImpl.address
);

console.log(
"To verify L1 bridge implementation contract: npx hardhat verify --network mainnet ",
bridgeImpl.address
);

fs.writeFileSync(
"deployment/L1BridgeImplementation.json",
JSON.stringify({
implementation: bridgeImpl.address,
})
);

return bridgeImpl.address;
} catch (error) {
console.log(error);
}
}

/**
* deploys and initializes the l2 governance relay
* @param l1GovRelay address
Expand Down
62 changes: 62 additions & 0 deletions scripts/deployUpdatedL1Bridge.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import { Contract } from "ethers";
import { STARKNET_MESSAGING_CONTRACT_MAINNET } from "./addresses";
import { StarknetContract } from "hardhat/types";
import fs from "fs";
import {
deployL1BridgeImplementation,
deployL1ForwarderStarknet,
} from "./deployBridge";
import { ethers } from "hardhat";
import { SignerWithAddress } from "@nomiclabs/hardhat-ethers/signers";
import { config as dotenvConfig } from "dotenv";
import { resolve } from "path";

dotenvConfig({ path: resolve(__dirname, "./.env") });

const { L2_DEPLOYER_PRIVATE_KEY, L2_DEPLOYER_ADDRESS } = process.env;

const maxFee = 5e16;

async function deployAll() {
try {
let l1deployer: SignerWithAddress;
let l1ForwarderStarknet: Contract;

if (!L2_DEPLOYER_PRIVATE_KEY || !L2_DEPLOYER_ADDRESS) {
throw new Error(
"Please set your L2 deployer private key & address in your .env file"
);
}

[l1deployer] = await ethers.getSigners();

if (!fs.existsSync("./deployment")) {
fs.mkdirSync("./deployment");
}

///////////////////////////
// L1 Forwarder Starknet //
///////////////////////////

l1ForwarderStarknet = await deployL1ForwarderStarknet(
l1deployer,
STARKNET_MESSAGING_CONTRACT_MAINNET,
"0x07bbb769e53d886f77792d59b9cd65a2eb14a84c49a0942ba9577e291deefcec"
);

//////////////////////////////
// L1 Bridge implementation //
//////////////////////////////

await deployL1BridgeImplementation(l1deployer);

console.log("Protocol deployed successfully!");

process.exit();
} catch (error) {
console.log(error);
process.exit(1);
}
}

deployAll();

0 comments on commit f0d201e

Please sign in to comment.