Module 0x7::trading_native_capability
Authorization layer for native-trading stores: the
TradingNativeCapability token that gates writes and the
ExchangeRegistry (at @aptos_experimental) that decides who can mint one.
Governance registers / denys exchanges; an exchange mints a cap
per tx via get_capability.
- Struct
Empty - Struct
TradingNativeCapability - Enum Resource
ExchangeRegistry - Constants
- Function
init_module - Function
is_denied - Function
register - Function
assert_active - Function
get_capability - Function
assert_valid - Function
deny - Function
reenable - Function
exchange
use 0x1::big_ordered_map;
use 0x1::error;
use 0x1::features;
use 0x1::signer;
use 0x1::system_addresses;
Struct Empty
Zero-sized value type for the BigOrderedMap sets (satisfies the
map's constant-serialized-size requirement).
struct Empty has copy, drop, store
Fields
-
dummy_field: bool
Struct TradingNativeCapability
store so the exchange can hold it across transactions; not
copy, so it can't be duplicated. Validity (registered, not
denied, flag enabled) is re-checked on every write via
assert_valid, so a stored cap stops working as soon as
governance denies the exchange.
struct TradingNativeCapability has drop, store
Fields
-
exchange: address
Enum Resource ExchangeRegistry
Registered exchanges and the governance deny-list, at
@aptos_experimental. BigOrderedMap keeps each entry in its own slot
so writes to distinct addresses don't contend under block-STM.
enum ExchangeRegistry has key
Variants
V1
Fields
-
registered: big_ordered_map::BigOrderedMap<address, trading_native_capability::Empty> -
denied: big_ordered_map::BigOrderedMap<address, trading_native_capability::Empty>
Constants
This exchange address has been disabled by governance.
const EEXCHANGE_DENIED: u64 = 3;
Exchange has not been registered yet.
const EEXCHANGE_NOT_REGISTERED: u64 = 2;
Feature TRADING_NATIVE is not enabled on this chain.
const EFEATURE_DISABLED: u64 = 1;
init_module was invoked with a signer other than @aptos_experimental.
const ENOT_DEPLOYER: u64 = 4;
Function init_module
Initialize the ExchangeRegistry at @aptos_experimental. Invoked by
vm-genesis (and on republish by the VM).
fun init_module(deployer: &signer)
Implementation
fun init_module(deployer: &signer) {
assert!(
signer::address_of(deployer) == @aptos_experimental,
error::permission_denied(ENOT_DEPLOYER),
);
if (!exists<ExchangeRegistry>(@aptos_experimental)) {
move_to(deployer, ExchangeRegistry::V1 {
registered: big_ordered_map::new(),
denied: big_ordered_map::new(),
});
};
}
Function is_denied
public fun is_denied(exchange: address): bool
Implementation
public fun is_denied(exchange: address): bool acquires ExchangeRegistry {
let registry = borrow_global<ExchangeRegistry>(@aptos_experimental);
registry.denied.contains(&exchange)
}
Function register
Governance-only: enroll an exchange. Idempotent.
public fun register(framework: &signer, exchange: address)
Implementation
public fun register(framework: &signer, exchange: address) acquires ExchangeRegistry {
system_addresses::assert_aptos_framework(framework);
assert!(
features::is_trading_native_enabled(),
error::permission_denied(EFEATURE_DISABLED),
);
let registry = borrow_global_mut<ExchangeRegistry>(@aptos_experimental);
if (!registry.registered.contains(&exchange)) {
registry.registered.add(exchange, Empty {});
};
}
Function assert_active
Abort unless addr is currently allowed to write: TRADING_NATIVE
enabled, registered, and not denied.
fun assert_active(addr: address)
Implementation
fun assert_active(addr: address) acquires ExchangeRegistry {
assert!(
features::is_trading_native_enabled(),
error::permission_denied(EFEATURE_DISABLED),
);
let registry = borrow_global<ExchangeRegistry>(@aptos_experimental);
assert!(
registry.registered.contains(&addr),
error::permission_denied(EEXCHANGE_NOT_REGISTERED),
);
assert!(
!registry.denied.contains(&addr),
error::permission_denied(EEXCHANGE_DENIED),
);
}
Function get_capability
Mint a cap for a registered, non-denied exchange. The caller may
store it; every write re-checks validity via assert_valid.
public fun get_capability(exchange: &signer): trading_native_capability::TradingNativeCapability
Implementation
public fun get_capability(exchange: &signer): TradingNativeCapability
acquires ExchangeRegistry {
let addr = signer::address_of(exchange);
assert_active(addr);
TradingNativeCapability { exchange: addr }
}
Function assert_valid
Abort unless cap's exchange is still allowed to write. Called on
every native-position write so a stored cap is invalidated the
moment governance denies the exchange (or the flag is turned off).
public fun assert_valid(cap: &trading_native_capability::TradingNativeCapability)
Implementation
public fun assert_valid(cap: &TradingNativeCapability) acquires ExchangeRegistry {
assert_active(cap.exchange);
}
Function deny
Governance-only: lock an exchange out (persisted state
untouched). Deliberately does not check TRADING_NATIVE —
governance must be able to lock out even with the flag off.
public fun deny(framework: &signer, exchange: address)
Implementation
public fun deny(framework: &signer, exchange: address) acquires ExchangeRegistry {
system_addresses::assert_aptos_framework(framework);
let registry = borrow_global_mut<ExchangeRegistry>(@aptos_experimental);
if (!registry.denied.contains(&exchange)) {
registry.denied.add(exchange, Empty {});
};
}
Function reenable
Governance-only: clear a deny. Like deny, does not check
TRADING_NATIVE.
public fun reenable(framework: &signer, exchange: address)
Implementation
public fun reenable(framework: &signer, exchange: address) acquires ExchangeRegistry {
system_addresses::assert_aptos_framework(framework);
let registry = borrow_global_mut<ExchangeRegistry>(@aptos_experimental);
if (registry.denied.contains(&exchange)) {
registry.denied.remove(&exchange);
};
}
Function exchange
public fun exchange(cap: &trading_native_capability::TradingNativeCapability): address
Implementation
public fun exchange(cap: &TradingNativeCapability): address {
cap.exchange
}