Skip to content

Commit

Permalink
Merge branch 'main' into add-wflow-handler
Browse files Browse the repository at this point in the history
  • Loading branch information
sisyphusSmiling committed Dec 2, 2024
2 parents 940d174 + 1ca51a6 commit 5924724
Show file tree
Hide file tree
Showing 23 changed files with 941 additions and 264 deletions.
25 changes: 8 additions & 17 deletions cadence/contracts/bridge/FlowEVMBridgeConfig.cdc
Original file line number Diff line number Diff line change
Expand Up @@ -229,18 +229,6 @@ contract FlowEVMBridgeConfig {
?? panic("Missing or mis-typed Blocklist in storage")
}

/// Temporary method to initialize the EVMBlocklist resource as this resource was added after the contract was
/// deployed
///
access(all)
fun initBlocklist() {
let path = /storage/evmBlocklist
if self.account.storage.type(at: path) != nil{
return
}
self.account.storage.save(<-create EVMBlocklist(), to: path)
}

/*****************
Constructs
*****************/
Expand Down Expand Up @@ -278,28 +266,28 @@ contract FlowEVMBridgeConfig {
access(all) resource EVMBlocklist {
/// Mapping of serialized EVM addresses to their blocked status
///
access(all) let blockList: {String: Bool}
access(all) let blocklist: {String: Bool}

init() {
self.blockList = {}
self.blocklist = {}
}

/// Returns whether the given EVM address is blocked from onboarding to the bridge
///
access(all) view fun isBlocked(_ evmAddress: EVM.EVMAddress): Bool {
return self.blockList[evmAddress.toString()] ?? false
return self.blocklist[evmAddress.toString()] ?? false
}

/// Blocks the given EVM address from onboarding to the bridge
///
access(Blocklist) fun block(_ evmAddress: EVM.EVMAddress) {
self.blockList[evmAddress.toString()] = true
self.blocklist[evmAddress.toString()] = true
}

/// Removes the given EVM address from the blocklist
///
access(Blocklist) fun unblock(_ evmAddress: EVM.EVMAddress) {
self.blockList.remove(key: evmAddress.toString())
self.blocklist.remove(key: evmAddress.toString())
}
}

Expand Down Expand Up @@ -500,5 +488,8 @@ contract FlowEVMBridgeConfig {
self.account.storage.save(<-create Admin(), to: self.adminStoragePath)
let adminCap = self.account.capabilities.storage.issue<&Admin>(self.adminStoragePath)
self.account.capabilities.publish(adminCap, at: self.adminPublicPath)

// Initialize the EVMBlocklist
self.account.storage.save(<-create EVMBlocklist(), to: /storage/evmBlocklist)
}
}
9 changes: 8 additions & 1 deletion cadence/contracts/bridge/FlowEVMBridgeNFTEscrow.cdc
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,14 @@ access(all) contract FlowEVMBridgeNFTEscrow {
locker.deposit(token: <-nft)
let postStorageSnapshot = self.account.storage.used

return postStorageSnapshot - preStorageSnapshot
// Return the amount of storage used by the locker after storing the NFT
if postStorageSnapshot < preStorageSnapshot {
// Due to atree inlining, account storage usage may counterintuitively decrease at times - return 0
return 0
} else {
// Otherwise, return the storage usage delta
return postStorageSnapshot - preStorageSnapshot
}
}

/// Unlocks the NFT of the given type and ID, reverting if it isn't in escrow
Expand Down
9 changes: 8 additions & 1 deletion cadence/contracts/bridge/FlowEVMBridgeTokenEscrow.cdc
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,14 @@ access(all) contract FlowEVMBridgeTokenEscrow {
locker.deposit(from: <-vault)
let postStorageSnapshot = self.account.storage.used

return postStorageSnapshot - preStorageSnapshot
// Return the amount of storage used by the locker after storing the NFT
if postStorageSnapshot < preStorageSnapshot {
// Due to atree inlining, account storage usage may counterintuitively decrease at times - return 0
return 0
} else {
// Otherwise, return the storage usage delta
return postStorageSnapshot - preStorageSnapshot
}
}

/// Unlocks the tokens of the given type and amount, reverting if it isn't in escrow
Expand Down
90 changes: 37 additions & 53 deletions cadence/contracts/utils/Serialize.cdc
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import "NonFungibleToken"
/// This contract is a utility for serializing primitive types, arrays, and common metadata mapping formats to JSON
/// compatible strings. Also included are interfaces enabling custom serialization for structs and resources.
///
/// Special thanks to @austinkline for the idea and initial implementation.
/// Special thanks to @austinkline for the idea and initial implementation & @bjartek + @bluesign for optimizations.
///
access(all)
contract Serialize {
Expand All @@ -27,59 +27,59 @@ contract Serialize {
case Type<Never?>():
return "\"nil\""
case Type<String>():
return "\"".concat(value as! String).concat("\"")
return String.join(["\"", value as! String, "\"" ], separator: "")
case Type<String?>():
return "\"".concat(value as? String ?? "nil").concat("\"")
return String.join(["\"", value as? String ?? "nil", "\"" ], separator: "")
case Type<Character>():
return "\"".concat((value as! Character).toString()).concat("\"")
return String.join(["\"", (value as! Character).toString(), "\"" ], separator: "")
case Type<Bool>():
return "\"".concat(value as! Bool ? "true" : "false").concat("\"")
return String.join(["\"", value as! Bool ? "true" : "false", "\"" ], separator: "")
case Type<Address>():
return "\"".concat((value as! Address).toString()).concat("\"")
return String.join(["\"", (value as! Address).toString(), "\"" ], separator: "")
case Type<Address?>():
return "\"".concat((value as? Address)?.toString() ?? "nil").concat("\"")
return String.join(["\"", (value as? Address)?.toString() ?? "nil", "\"" ], separator: "")
case Type<Int8>():
return "\"".concat((value as! Int8).toString()).concat("\"")
return String.join(["\"", (value as! Int8).toString(), "\"" ], separator: "")
case Type<Int16>():
return "\"".concat((value as! Int16).toString()).concat("\"")
return String.join(["\"", (value as! Int16).toString(), "\"" ], separator: "")
case Type<Int32>():
return "\"".concat((value as! Int32).toString()).concat("\"")
return String.join(["\"", (value as! Int32).toString(), "\"" ], separator: "")
case Type<Int64>():
return "\"".concat((value as! Int64).toString()).concat("\"")
return String.join(["\"", (value as! Int64).toString(), "\"" ], separator: "")
case Type<Int128>():
return "\"".concat((value as! Int128).toString()).concat("\"")
return String.join(["\"", (value as! Int128).toString(), "\"" ], separator: "")
case Type<Int256>():
return "\"".concat((value as! Int256).toString()).concat("\"")
return String.join(["\"", (value as! Int256).toString(), "\"" ], separator: "")
case Type<Int>():
return "\"".concat((value as! Int).toString()).concat("\"")
return String.join(["\"", (value as! Int).toString(), "\"" ], separator: "")
case Type<UInt8>():
return "\"".concat((value as! UInt8).toString()).concat("\"")
return String.join(["\"", (value as! UInt8).toString(), "\"" ], separator: "")
case Type<UInt16>():
return "\"".concat((value as! UInt16).toString()).concat("\"")
return String.join(["\"", (value as! UInt16).toString(), "\"" ], separator: "")
case Type<UInt32>():
return "\"".concat((value as! UInt32).toString()).concat("\"")
return String.join(["\"", (value as! UInt32).toString(), "\"" ], separator: "")
case Type<UInt64>():
return "\"".concat((value as! UInt64).toString()).concat("\"")
return String.join(["\"", (value as! UInt64).toString(), "\"" ], separator: "")
case Type<UInt128>():
return "\"".concat((value as! UInt128).toString()).concat("\"")
return String.join(["\"", (value as! UInt128).toString(), "\"" ], separator: "")
case Type<UInt256>():
return "\"".concat((value as! UInt256).toString()).concat("\"")
return String.join(["\"", (value as! UInt256).toString(), "\"" ], separator: "")
case Type<UInt>():
return "\"".concat((value as! UInt).toString()).concat("\"")
return String.join(["\"", (value as! UInt).toString(), "\"" ], separator: "")
case Type<Word8>():
return "\"".concat((value as! Word8).toString()).concat("\"")
return String.join(["\"", (value as! Word8).toString(), "\"" ], separator: "")
case Type<Word16>():
return "\"".concat((value as! Word16).toString()).concat("\"")
return String.join(["\"", (value as! Word16).toString(), "\"" ], separator: "")
case Type<Word32>():
return "\"".concat((value as! Word32).toString()).concat("\"")
return String.join(["\"", (value as! Word32).toString(), "\"" ], separator: "")
case Type<Word64>():
return "\"".concat((value as! Word64).toString()).concat("\"")
return String.join(["\"", (value as! Word64).toString(), "\"" ], separator: "")
case Type<Word128>():
return "\"".concat((value as! Word128).toString()).concat("\"")
return String.join(["\"", (value as! Word128).toString(), "\"" ], separator: "")
case Type<Word256>():
return "\"".concat((value as! Word256).toString()).concat("\"")
return String.join(["\"", (value as! Word256).toString(), "\"" ], separator: "")
case Type<UFix64>():
return "\"".concat((value as! UFix64).toString()).concat("\"")
return String.join(["\"", (value as! UFix64).toString(), "\"" ], separator: "")
default:
return nil
}
Expand All @@ -89,24 +89,15 @@ contract Serialize {
///
access(all)
fun arrayToJSONString(_ arr: [AnyStruct]): String? {
var serializedArr = "["
let arrLength = arr.length
for i, element in arr {
let parts: [String]= []
for element in arr {
let serializedElement = self.tryToJSONString(element)
if serializedElement == nil {
if i == arrLength - 1 && serializedArr.length > 1 && serializedArr[serializedArr.length - 2] == "," {
// Remove trailing comma as this element could not be serialized
serializedArr = serializedArr.slice(from: 0, upTo: serializedArr.length - 2)
}
continue
}
serializedArr = serializedArr.concat(serializedElement!)
// Add a comma if there are more elements to serialize
if i < arr.length - 1 {
serializedArr = serializedArr.concat(", ")
}
parts.append(serializedElement!)
}
return serializedArr.concat("]")
return "[".concat(String.join(parts, separator: ", ")).concat("]")
}

/// Returns a serialized representation of the given String-indexed mapping or nil if the value is not serializable.
Expand All @@ -120,22 +111,15 @@ contract Serialize {
dict.remove(key: k)
}
}
var serializedDict = "{"
let dictLength = dict.length
for i, key in dict.keys {
let parts: [String] = []
for key in dict.keys {
let serializedValue = self.tryToJSONString(dict[key]!)
if serializedValue == nil {
if i == dictLength - 1 && serializedDict.length > 1 && serializedDict[serializedDict.length - 2] == "," {
// Remove trailing comma as this element could not be serialized
serializedDict = serializedDict.slice(from: 0, upTo: serializedDict.length - 2)
}
continue
}
serializedDict = serializedDict.concat(self.tryToJSONString(key)!).concat(": ").concat(serializedValue!)
if i < dict.length - 1 {
serializedDict = serializedDict.concat(", ")
}
let serialializedKeyValue = String.join([self.tryToJSONString(key)!, serializedValue!], separator: ": ")
parts.append(serialializedKeyValue)
}
return serializedDict.concat("}")
return "{".concat(String.join(parts, separator: ", ")).concat("}")
}
}
Loading

0 comments on commit 5924724

Please sign in to comment.