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

Aptos v2 Core Protocol #131

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
17 changes: 17 additions & 0 deletions packages/layerzero-v2/aptos/contracts/deployer/Move.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
[package]
name = "deployer"
version = "1.0.0"
authors = []

[addresses]
deployer = "_"

[dev-addresses]
deployer = "0x90909090"

[dependencies.AptosFramework]
git = "https://github.com/aptos-labs/aptos-framework.git"
rev = "mainnet"
subdir = "aptos-framework"

[dev-dependencies]
Original file line number Diff line number Diff line change
@@ -0,0 +1,206 @@
/// This is a fork of the original code from the Move standard library.
/// The original code can be found at aptos_framework::object_code_deployment.
/// This has been modified for the following:
/// 1) Accept a seed for the object creation to provide deterministic addresses
/// 2) Convenience view function to generate the object address given the publisher address and the object seed.
/// 3) Function to generate a signer for the code object to be used in scripts
/// 4) Function to destroy the ExtendRef for the code object
/// 5) Extract repeated code into a function to assert the owner of the code object
///
/// ===================================================================================================================
///
/// This module allows users to deploy, upgrade and freeze modules deployed to objects on-chain.
/// This enables users to deploy modules to an object with a unique address each time they are published.
/// This modules provides an alternative method to publish code on-chain, where code is deployed to objects rather than accounts.
/// This is encouraged as it abstracts the necessary resources needed for deploying modules,
/// along with the required authorization to upgrade and freeze modules.
///
/// The functionalities of this module are as follows.
///
/// Publishing modules flow:
/// 1. Create a new object with the address derived from the publisher address and the object seed.
/// 2. Publish the module passed in the function via `metadata_serialized` and `code` to the newly created object.
/// 3. Emits 'Publish' event with the address of the newly created object.
/// 4. Create a `ManagingRefs` which stores the extend ref of the newly created object.
/// Note: This is needed to upgrade the code as the signer must be generated to upgrade the existing code in an object.
///
/// Upgrading modules flow:
/// 1. Assert the `code_object` passed in the function is owned by the `publisher`.
/// 2. Assert the `code_object` passed in the function exists in global storage.
/// 2. Retrieve the `ExtendRef` from the `code_object` and generate the signer from this.
/// 3. Upgrade the module with the `metadata_serialized` and `code` passed in the function.
/// 4. Emits 'Upgrade' event with the address of the object with the upgraded code.
/// Note: If the modules were deployed as immutable when calling `publish`, the upgrade will fail.
///
/// Freezing modules flow:
/// 1. Assert the `code_object` passed in the function exists in global storage.
/// 2. Assert the `code_object` passed in the function is owned by the `publisher`.
/// 3. Mark all the modules in the `code_object` as immutable.
/// 4. Emits 'Freeze' event with the address of the object with the frozen code.
/// Note: There is no unfreeze function as this gives no benefit if the user can freeze/unfreeze modules at will.
/// Once modules are marked as immutable, they cannot be made mutable again.
module deployer::object_code_deployment {
use std::error;
use std::signer;
use std::code;
use std::event;
use std::object::{Self, address_to_object, ExtendRef, ObjectCore};

/// Object code deployment feature not supported.
const EOBJECT_CODE_DEPLOYMENT_NOT_SUPPORTED: u64 = 1;
/// Not the owner of the `code_object`
const ENOT_CODE_OBJECT_OWNER: u64 = 2;
/// `code_object` does not exist.
const ECODE_OBJECT_DOES_NOT_EXIST: u64 = 3;
/// Arbitrary signer generation is disabled for the code object.
const EARBITRARY_SIGNER_DISABLED: u64 = 4;

const OBJECT_CODE_DEPLOYMENT_DOMAIN_SEPARATOR: vector<u8> = b"aptos_framework::object_code_deployment";

#[resource_group_member(group = aptos_framework::object::ObjectGroup)]
/// Internal struct, attached to the object, that holds Refs we need to manage the code deployment (i.e. upgrades).
struct ManagingRefs has key {
/// We need to keep the extend ref to be able to generate the signer to upgrade existing code.
extend_ref: ExtendRef,
/// This flag controls whether this module can release a signer for the code object.
arbitrary_signer_enabled: bool,
}

#[event]
/// Event emitted when code is published to an object.
struct Publish has drop, store {
object_address: address,
}

#[event]
/// Event emitted when code in an existing object is upgraded.
struct Upgrade has drop, store {
object_address: address,
}

#[event]
/// Event emitted when code in an existing object is made immutable.
struct Freeze has drop, store {
object_address: address,
}

#[event]
struct DisableArbitrarySigner has drop, store {
object_address: address,
}

#[event]
struct DestroyRefs has drop, store {
object_address: address,
}

#[view]
/// Gets the object address given the publisher address and the object seed
public fun compute_object_address(publisher: address, object_seed: vector<u8>): address {
object::create_object_address(&publisher, object_seed)
}

/// Creates a new object with a unique address derived from the publisher address and the object seed.
/// Publishes the code passed in the function to the newly created object.
/// The caller must provide package metadata describing the package via `metadata_serialized` and
/// the code to be published via `code`. This contains a vector of modules to be deployed on-chain.
public entry fun publish(
publisher: &signer,
object_seed: vector<u8>,
metadata_serialized: vector<u8>,
code: vector<vector<u8>>,
) {
let constructor_ref = &object::create_named_object(publisher, object_seed);
let code_signer = &object::generate_signer(constructor_ref);
code::publish_package_txn(code_signer, metadata_serialized, code);

event::emit(Publish { object_address: signer::address_of(code_signer) });

move_to(code_signer, ManagingRefs {
extend_ref: object::generate_extend_ref(constructor_ref),
arbitrary_signer_enabled: true,
});
}

/// Upgrades the existing modules at the `code_object` address with the new modules passed in `code`,
/// along with the metadata `metadata_serialized`.
/// Note: If the modules were deployed as immutable when calling `publish`, the upgrade will fail.
/// Requires the publisher to be the owner of the `code_object`.
public entry fun upgrade(
publisher: &signer,
metadata_serialized: vector<u8>,
code: vector<vector<u8>>,
code_object: address,
) acquires ManagingRefs {
assert_owner_and_code_object(signer::address_of(move publisher), code_object);

let extend_ref = &borrow_global<ManagingRefs>(code_object).extend_ref;
let code_signer = &object::generate_signer_for_extending(extend_ref);
code::publish_package_txn(code_signer, metadata_serialized, code);

event::emit(Upgrade { object_address: signer::address_of(code_signer) });
}

/// Get an arbitrary signer for the code object, which can be used in scripts or other transactions.
public fun get_code_object_signer(
publisher: &signer,
code_object: address,
): signer acquires ManagingRefs {
assert_owner_and_code_object(signer::address_of(move publisher), code_object);

// Check if arbitrary signer generation is enabled for the code object
assert!(
borrow_global<ManagingRefs>(code_object).arbitrary_signer_enabled,
EARBITRARY_SIGNER_DISABLED,
);

let extend_ref = &borrow_global<ManagingRefs>(code_object).extend_ref;
object::generate_signer_for_extending(extend_ref)
}

/// Disable the ability to generate arbitrary signers for the code object.
public entry fun disable_arbitrary_signer(publisher: &signer, code_object: address) acquires ManagingRefs {
let publisher_address = signer::address_of(move publisher);
assert_owner_and_code_object(publisher_address, code_object);

// Permanently disable the ability to generate arbitrary signers for the code object
borrow_global_mut<ManagingRefs>(code_object).arbitrary_signer_enabled = false;

event::emit(DisableArbitrarySigner { object_address: code_object });
}

/// Make an existing upgradable package immutable. Once this is called, the package cannot be made upgradable again.
/// Each `code_object` should only have one package, as one package is deployed per object in this module.
/// Requires the `publisher` to be the owner of the `code_object`.
public entry fun freeze_code_object(publisher: &signer, code_object: address) {
code::freeze_code_object(publisher, address_to_object(code_object));

event::emit(Freeze { object_address: code_object });
}

/// This permanently destroys the ability to upgrade or sign on behalf of the code object.
/// This is effectively equivalent to transferring the code object to a burn object, but is more explicit in
/// destroying the ExtendRef.
public entry fun destroy_refs(publisher: &signer, code_object: address) acquires ManagingRefs {
let publisher_address = signer::address_of(move publisher);
assert_owner_and_code_object(publisher_address, code_object);

let ManagingRefs {
extend_ref: _,
arbitrary_signer_enabled: _,
} = move_from<ManagingRefs>(publisher_address);

event::emit(DestroyRefs { object_address: code_object });
}

/// Internal function to assert the owner of the `code_object` and asset that there is a code object at the location
fun assert_owner_and_code_object(publisher_address: address, code_object: address) {
assert!(
object::is_owner(address_to_object<ObjectCore>(code_object), publisher_address),
error::permission_denied(ENOT_CODE_OBJECT_OWNER),
);

let code_object_address = code_object;
assert!(exists<ManagingRefs>(code_object_address), error::not_found(ECODE_OBJECT_DOES_NOT_EXIST));
}
}
67 changes: 67 additions & 0 deletions packages/layerzero-v2/aptos/contracts/endpoint_v2/Move.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
[package]
name = "endpoint_v2"
version = "1.0.0"
authors = []

[addresses]
router_node_0 = "_"
simple_msglib = "_"
blocked_msglib = "_"
uln_302 = "_"
router_node_1 = "_"
endpoint_v2_common = "_"
endpoint_v2 = "_"
layerzero_admin = "_"
layerzero_treasury_admin = "_"
msglib_types = "_"
treasury = "_"
executor_fee_lib_router_0 = "_"
executor_fee_lib_router_1 = "_"
dvn_fee_lib_router_0 = "_"
dvn_fee_lib_router_1 = "_"
price_feed_router_0 = "_"
price_feed_router_1 = "_"
price_feed_module_0 = "_"
worker_common = "_"
executor_fee_lib_0 = "_"
dvn_fee_lib_0 = "_"
dvn = "_"
native_token_metadata_address = "0xa"
# For Initia: "0x8e4733bdabcf7d4afc3d14f0dd46c9bf52fb0fce9e4b996c939e195b8bc891d9"

[dev-addresses]
router_node_0 = "0x9001"
simple_msglib = "0x9002"
blocked_msglib = "0x9003"
uln_302 = "0x9005"
router_node_1 = "0x9007"
endpoint_v2_common = "0x9098"
endpoint_v2 = "0x12345678"
layerzero_admin = "0x18943124"
layerzero_treasury_admin = "0x1894312499"
msglib_types = "0x5211234"
treasury = "0x123432432"
executor_fee_lib_router_0 = "0x30001"
executor_fee_lib_router_1 = "0x3465342143"
dvn_fee_lib_router_0 = "0x30001a"
dvn_fee_lib_router_1 = "0x3465342143a"
price_feed_router_0 = "0x65DD71A"
price_feed_router_1 = "0x65DD71AB"
price_feed_module_0 = "0x65DD71"
worker_common = "0x3999"
executor_fee_lib_0 = "0x3000"
dvn_fee_lib_0 = "0x3000a"
dvn = "0x22314321"

[dev-dependencies]
simple_msglib = { local = "../msglib/libs/simple_msglib" }
uln_302 = { local = "../msglib/libs/uln_302" }
worker_common = { local = "../worker_peripherals/worker_common" }
executor_fee_lib_0 = { local = "../worker_peripherals/fee_libs/executor_fee_lib_0" }
dvn_fee_lib_0 = { local = "../worker_peripherals/fee_libs/dvn_fee_lib_0" }

[dependencies]
msglib_types = { local = "../msglib/msglib_types" }
router_node_0 = { local = "../msglib/routers/router_node_0" }
endpoint_v2_common = { local = "../endpoint_v2_common" }
price_feed_module_0 = { local = "../worker_peripherals/price_feed_modules/price_feed_module_0" }
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/// This module isolates functions related to Endpoint administration
module endpoint_v2::admin {
use std::signer::address_of;

use endpoint_v2::msglib_manager;

/// Register new message library
/// A library must be registered to be called by this endpoint. Once registered, it cannot be unregistered. The
/// library must be connected to the router node before it can be registered
public entry fun register_library(account: &signer, lib: address) {
assert_admin(address_of(move account));
msglib_manager::register_library(lib);
}

/// Sets the default sending message library for the given destination EID
public entry fun set_default_send_library(account: &signer, dst_eid: u32, lib: address) {
assert_admin(address_of(move account));
msglib_manager::set_default_send_library(dst_eid, lib);
}

/// Set the default receive message library for the given source EID
public entry fun set_default_receive_library(
account: &signer,
src_eid: u32,
lib: address,
grace_period: u64,
) {
assert_admin(address_of(move account));
msglib_manager::set_default_receive_library(src_eid, lib, grace_period);
}

/// Updates the default receive library timeout for the given source EID
/// The provided expiry is in a specific block number. The fallback library will be disabled once the block height
/// equals this block number
public entry fun set_default_receive_library_timeout(
account: &signer,
src_eid: u32,
fallback_lib: address,
expiry: u64,
) {
assert_admin(address_of(move account));
msglib_manager::set_default_receive_library_timeout(src_eid, fallback_lib, expiry);
}

// ==================================================== Helpers ===================================================

/// Internal function to assert that the caller is the endpoint admin
inline fun assert_admin(admin: address) {
assert!(admin == @layerzero_admin, EUNAUTHORIZED);
}

#[test_only]
/// Test-only function to initialize the endpoint and EID
public fun initialize_endpoint_for_test() {
endpoint_v2::store::init_module_for_test();
}

// ================================================== Error Codes =================================================

const EUNAUTHORIZED: u64 = 1;
}
Loading
Loading