Skip to content

Commit

Permalink
Merge pull request #139 from onflow/gio/add-cadence-onboarding-blocklist
Browse files Browse the repository at this point in the history
Add Cadence Type onboarding blocklist functionality
  • Loading branch information
sisyphusSmiling authored Dec 19, 2024
2 parents 1ca51a6 + 1946a8a commit 8765428
Show file tree
Hide file tree
Showing 6 changed files with 141 additions and 5 deletions.
4 changes: 3 additions & 1 deletion cadence/contracts/bridge/FlowEVMBridge.cdc
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ contract FlowEVMBridge : IFlowEVMNFTBridge, IFlowEVMTokenBridge {
!FlowEVMBridgeConfig.isPaused(): "Bridge operations are currently paused"
type != Type<@FlowToken.Vault>():
"$FLOW cannot be bridged via the VM bridge - use the CadenceOwnedAccount interface"
!FlowEVMBridgeConfig.isCadenceTypeBlocked(type):
"This Cadence Type ".concat(type.identifier).concat(" is currently blocked from being onboarded")
self.typeRequiresOnboarding(type) == true: "Onboarding is not needed for this type"
FlowEVMBridgeUtils.typeAllowsBridging(type):
"This type is not supported as defined by the project's development team"
Expand Down Expand Up @@ -144,7 +146,7 @@ contract FlowEVMBridge : IFlowEVMNFTBridge, IFlowEVMTokenBridge {
pre {
!FlowEVMBridgeConfig.isPaused(): "Bridge operations are currently paused"
!FlowEVMBridgeConfig.isEVMAddressBlocked(address):
"This EVM contract is currently blocked from being onboarded"
"This EVM contract ".concat(address.toString()).concat(" is currently blocked from being onboarded")
}
/* Validate the EVM contract */
//
Expand Down
63 changes: 59 additions & 4 deletions cadence/contracts/bridge/FlowEVMBridgeConfig.cdc
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,14 @@ contract FlowEVMBridgeConfig {
///
access(all)
view fun isEVMAddressBlocked(_ evmAddress: EVM.EVMAddress): Bool {
return self.borrowBlocklist().isBlocked(evmAddress)
return self.borrowEVMBlocklist().isBlocked(evmAddress)
}

/// Returns whether the given Cadence Type is currently blocked from onboarding to the bridge
///
access(all)
view fun isCadenceTypeBlocked(_ type: Type): Bool {
return self.borrowCadenceBlocklist().isBlocked(type)
}

/****************************
Expand Down Expand Up @@ -224,9 +231,17 @@ contract FlowEVMBridgeConfig {
/// Returns an entitled reference to the bridge EVMBlocklist
///
access(self)
view fun borrowBlocklist(): auth(Blocklist) &EVMBlocklist {
view fun borrowEVMBlocklist(): auth(Blocklist) &EVMBlocklist {
return self.account.storage.borrow<auth(Blocklist) &EVMBlocklist>(from: /storage/evmBlocklist)
?? panic("Missing or mis-typed Blocklist in storage")
?? panic("Missing or mis-typed EVMBlocklist in storage")
}

/// Returns an entitled reference to the bridge CadenceBlocklist
///
access(self)
view fun borrowCadenceBlocklist(): auth(Blocklist) &CadenceBlocklist {
return self.account.storage.borrow<auth(Blocklist) &CadenceBlocklist>(from: /storage/cadenceBlocklist)
?? panic("Missing or mis-typed CadenceBlocklist in storage")
}

/*****************
Expand Down Expand Up @@ -291,6 +306,45 @@ contract FlowEVMBridgeConfig {
}
}

access(all) fun initCadenceBlocklist() {
let cadenceBlocklistStoragePath = /storage/cadenceBlocklist
assert(
self.account.storage.type(at: cadenceBlocklistStoragePath) == nil,
message: "CadenceBlocklist already stored"
)
self.account.storage.save(<-create CadenceBlocklist(), to: cadenceBlocklistStoragePath)
}

/// CadenceBlocklist resource stores a mapping of Cadence Types that are blocked from onboarding to the bridge
///
access(all) resource CadenceBlocklist {
/// Mapping of serialized Cadence Type to their blocked status
///
access(all) let blocklist: {Type: Bool}

init() {
self.blocklist = {}
}

/// Returns whether the given Type is blocked from onboarding to the bridge
///
access(all) view fun isBlocked(_ type: Type): Bool {
return self.blocklist[type] ?? false
}

/// Blocks the given Type from onboarding to the bridge
///
access(Blocklist) fun block(_ type: Type) {
self.blocklist[type] = true
}

/// Removes the given type from the blocklist
///
access(Blocklist) fun unblock(_ type: Type) {
self.blocklist.remove(key: type)
}
}

/*****************
Config Admin
*****************/
Expand Down Expand Up @@ -497,7 +551,8 @@ contract FlowEVMBridgeConfig {
let adminCap = self.account.capabilities.storage.issue<&Admin>(self.adminStoragePath)
self.account.capabilities.publish(adminCap, at: self.adminPublicPath)

// Initialize the EVMBlocklist
// Initialize the blocklists
self.account.storage.save(<-create EVMBlocklist(), to: /storage/evmBlocklist)
self.account.storage.save(<-create CadenceBlocklist(), to: /storage/cadenceBlocklist)
}
}
14 changes: 14 additions & 0 deletions cadence/scripts/bridge/is_cadence_type_blocked.cdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import "EVM"

import "FlowEVMBridgeConfig"

/// Returns whether a Cadence Type is blocked from onboarded to the FlowEVMBridge
///
/// @param typeIdentifier: The Cadence Type identifier of the asset in question
///
/// @return Whether the Cadence type is blocked from onboarding to the FlowEVMBridge
///
access(all) fun main(typeIdentifier: String): Bool {
let type = CompositeType(typeIdentifier) ?? panic("Invalid type identifier ".concat(typeIdentifier))
return FlowEVMBridgeConfig.isCadenceTypeBlocked(type)
}
28 changes: 28 additions & 0 deletions cadence/transactions/bridge/admin/blocklist/block_cadence_type.cdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import "EVM"

import "FlowEVMBridgeConfig"

/// Blocks the given Cadence Type from onboarding.
///
/// @param typeIdentifier: The Cadence identifier of the type to block
///
transaction(typeIdentifier: String) {

let cadenceBlocklist: auth(FlowEVMBridgeConfig.Blocklist) &FlowEVMBridgeConfig.CadenceBlocklist
let type: Type

prepare(signer: auth(BorrowValue) &Account) {
self.cadenceBlocklist = signer.storage.borrow<auth(FlowEVMBridgeConfig.Blocklist) &FlowEVMBridgeConfig.CadenceBlocklist>(
from: /storage/cadenceBlocklist
) ?? panic("Could not borrow FlowEVMBridgeConfig Admin reference")
self.type = CompositeType(typeIdentifier) ?? panic("Invalid type identifier ".concat(typeIdentifier))
}

execute {
self.cadenceBlocklist.block(self.type)
}

post {
FlowEVMBridgeConfig.isCadenceTypeBlocked(self.type): "Type was not blocked"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import "FlowEVMBridgeConfig"

transaction {
prepare(signer: &Account) {}

execute {
FlowEVMBridgeConfig.initCadenceBlocklist()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import "EVM"

import "FlowEVMBridgeConfig"

/// Unblocks the given Cadence Type from onboarding.
///
/// @param typeIdentifier: The Cadence identifier of the type to block
///
transaction(typeIdentifier: String) {

let cadenceBlocklist: auth(FlowEVMBridgeConfig.Blocklist) &FlowEVMBridgeConfig.CadenceBlocklist
let type: Type

prepare(signer: auth(BorrowValue) &Account) {
self.cadenceBlocklist = signer.storage.borrow<auth(FlowEVMBridgeConfig.Blocklist) &FlowEVMBridgeConfig.CadenceBlocklist>(
from: /storage/cadenceBlocklist
) ?? panic("Could not borrow FlowEVMBridgeConfig Admin reference")
self.type = CompositeType(typeIdentifier) ?? panic("Invalid type identifier ".concat(typeIdentifier))
}

execute {
self.cadenceBlocklist.unblock(self.type)
}

post {
!FlowEVMBridgeConfig.isCadenceTypeBlocked(self.type): "Type was not unblocked"
}
}

0 comments on commit 8765428

Please sign in to comment.