Module 0x2::deny_list
Defines the DenyList type. The DenyList shared object is used to restrict access to instances of certain core types from being used as inputs by specified addresses in the deny list.
- Resource
DenyList
- Resource
PerTypeList
- Constants
- Function
add
- Function
per_type_list_add
- Function
remove
- Function
per_type_list_remove
- Function
contains
- Function
per_type_list_contains
- Function
create
- Function
per_type_list
use 0x1::vector;
use 0x2::bag;
use 0x2::object;
use 0x2::table;
use 0x2::transfer;
use 0x2::tx_context;
use 0x2::vec_set;
Resource DenyList
A shared object that stores the addresses that are blocked for a given core type.
struct DenyList has key
Fields
- id: object::UID
- lists: bag::Bag
- The individual deny lists.
Resource PerTypeList
Stores the addresses that are denied for a given core type.
struct PerTypeList has store, key
Fields
- id: object::UID
- denied_count: table::Table<address, u64>
- Number of object types that have been banned for a given address. Used to quickly skip checks for most addresses.
- denied_addresses: table::Table<vector<u8>, vec_set::VecSet<address>>
- Set of addresses that are banned for a given type. For example with sui::coin::Coin: If addresses A and B are banned from using "0...0123::my_coin::MY_COIN", this will be "0...0123::my_coin::MY_COIN" -> {A, B}.
Constants
Trying to create a deny list object when not called by the system address.
const ENotSystemAddress: u64 = 0;
The index into the deny list vector for the sui::coin::Coin type.
const COIN_INDEX: u64 = 0;
The specified address cannot be added to the deny list.
const EInvalidAddress: u64 = 1;
The specified address to be removed is not already in the deny list.
const ENotDenied: u64 = 1;
These addresses are reserved and cannot be added to the deny list. The addresses listed are well known package and object addresses. So it would be meaningless to add them to the deny list.
const RESERVED: vector<address> = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 1027, 57065];
Function add
Adds the given address to the deny list of the specified type, preventing it from interacting with instances of that type as an input to a transaction. For coins, the type specified is the type of the coin, not the coin type itself. For example, "00...0123::my_coin::MY_COIN" would be the type, not "00...02::coin::Coin".
public(friend) fun add(deny_list: &mut deny_list::DenyList, per_type_index: u64, type: vector<u8>, addr: address)
Implementation
public(package) fun add(
deny_list: &mut DenyList,
per_type_index: u64,
`type`: vector<u8>,
addr: address,
) {
let reserved = RESERVED;
assert!(!reserved.contains(&addr), EInvalidAddress);
let bag_entry: &mut PerTypeList = &mut deny_list.lists[per_type_index];
bag_entry.per_type_list_add(`type`, addr)
}
Function per_type_list_add
fun per_type_list_add(list: &mut deny_list::PerTypeList, type: vector<u8>, addr: address)
Implementation
fun per_type_list_add(
list: &mut PerTypeList,
`type`: vector<u8>,
addr: address,
) {
if (!list.denied_addresses.contains(`type`)) {
list.denied_addresses.add(`type`, vec_set::empty());
};
let denied_addresses = &mut list.denied_addresses[`type`];
let already_denied = denied_addresses.contains(&addr);
if (already_denied) return;
denied_addresses.insert(addr);
if (!list.denied_count.contains(addr)) {
list.denied_count.add(addr, 0);
};
let denied_count = &mut list.denied_count[addr];
*denied_count = *denied_count + 1;
}
Function remove
Removes a previously denied address from the list. Aborts with ENotDenied if the address is not on the list.
public(friend) fun remove(deny_list: &mut deny_list::DenyList, per_type_index: u64, type: vector<u8>, addr: address)
Implementation
public(package) fun remove(
deny_list: &mut DenyList,
per_type_index: u64,
`type`: vector<u8>,
addr: address,
) {
let reserved = RESERVED;
assert!(!reserved.contains(&addr), EInvalidAddress);
per_type_list_remove(&mut deny_list.lists[per_type_index], `type`, addr)
}
Function per_type_list_remove
fun per_type_list_remove(list: &mut deny_list::PerTypeList, type: vector<u8>, addr: address)
Implementation
fun per_type_list_remove(
list: &mut PerTypeList,
`type`: vector<u8>,
addr: address,
) {
let denied_addresses = &mut list.denied_addresses[`type`];
assert!(denied_addresses.contains(&addr), ENotDenied);
denied_addresses.remove(&addr);
let denied_count = &mut list.denied_count[addr];
*denied_count = *denied_count - 1;
if (*denied_count == 0) {
list.denied_count.remove(addr);
}
}
Function contains
Returns true iff the given address is denied for the given type.
public(friend) fun contains(deny_list: &deny_list::DenyList, per_type_index: u64, type: vector<u8>, addr: address): bool
Implementation
Function per_type_list_contains
fun per_type_list_contains(list: &deny_list::PerTypeList, type: vector<u8>, addr: address): bool
Implementation
fun per_type_list_contains(
list: &PerTypeList,
`type`: vector<u8>,
addr: address,
): bool {
if (!list.denied_count.contains(addr)) return false;
let denied_count = &list.denied_count[addr];
if (*denied_count == 0) return false;
if (!list.denied_addresses.contains(`type`)) return false;
let denied_addresses = &list.denied_addresses[`type`];
denied_addresses.contains(&addr)
}
Function create
Creation of the deny list object is restricted to the system address via a system transaction.
fun create(ctx: &mut tx_context::TxContext)
Implementation
fun create(ctx: &mut TxContext) {
assert!(ctx.sender() == @0x0, ENotSystemAddress);
let mut lists = bag::new(ctx);
lists.add(COIN_INDEX, per_type_list(ctx));
let deny_list_object = DenyList {
id: object::sui_deny_list_object_id(),
lists,
};
transfer::share_object(deny_list_object);
}
Function per_type_list
fun per_type_list(ctx: &mut tx_context::TxContext): deny_list::PerTypeList
Implementation
fun per_type_list(ctx: &mut TxContext): PerTypeList {
PerTypeList {
id: object::new(ctx),
denied_count: table::new(ctx),
denied_addresses: table::new(ctx),
}
}