-
Notifications
You must be signed in to change notification settings - Fork 106
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add wrapper functionality & bridge integration (#281)
* add creator token functionality & interfaces * implement wrapper * add bridge & wrap txs, baseTokenURI * call hook from _update (oz v5 removed hooks), add IERC2981 conformance * add comments * add bridge permissions, fulfillment * add bridge tests * fix ci * rename param * update bridge extensions * add tests, comments * update readme * add unwrap, transfer txs * update readme * update bridge interface from flow-evm-bridge #168 * add metadata events * fix readme, tx param * fix unwrap tx * update readme * rename method * implement IERC2981 * keep event declaration * update crossvm extensions to final * address pr comments * add CrossVMMetadataViews view * add tx fixes, pr comments * fix ci * fix type * fix permissions updated event * fix tx * add IERC4906 * fix isNFTWrapped, royalty tx * return false if empty * fix type * fix tx param * fix tx * parameterize address in metdata view * fix tests * fix json * uint256 type * add log details * increase gas limit * rename txs * add comments
- Loading branch information
Showing
40 changed files
with
2,156 additions
and
2,388 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,3 +4,4 @@ flow.json | |
.vscode | ||
.env | ||
**/vendor/ | ||
*.pkey |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,3 @@ | ||
export GOFLAGS :=-tags=no_cgo | ||
export CGO_ENABLED := 0 | ||
|
||
.PHONY: test | ||
test: | ||
$(MAKE) generate -C lib/go | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
import ViewResolver from 0xVIEWRESOLVERADDRESS | ||
import EVM from 0xEVMADDRESS | ||
|
||
/// This contract implements views originally proposed in FLIP-318 supporting NFT collections | ||
/// with project-defined implementations across both Cadence & EVM. | ||
/// The View structs in this contract should be implemented in the same way that views from `MetadataViews` are implemented | ||
/// | ||
access(all) contract CrossVMMetadataViews { | ||
|
||
/// An enum denoting a VM. For now, there are only two VMs on Flow, but this enum could be | ||
/// expanded in the event other VMs are supported on the network. | ||
/// | ||
access(all) enum VM : UInt8 { | ||
access(all) case Cadence | ||
access(all) case EVM | ||
} | ||
|
||
/// View resolved at contract & resource level pointing to the associated EVM implementation. | ||
/// NOTE: This view alone is not sufficient to validate an association across Cadence & EVM! | ||
/// Both the Cadence Type/contract *and* the EVM contract should point to each other, with the | ||
/// EVM pointer being facilitated by ICrossVM.sol contract interface methods. For more | ||
/// information and context, see FLIP-318: https://github.com/onflow/flips/issues/318 | ||
/// | ||
access(all) struct EVMPointer { | ||
/// The associated Cadence Type defined in the contract that this view is returned from | ||
access(all) let cadenceType: Type | ||
/// The defining Cadence contract address | ||
access(all) let cadenceContractAddress: Address | ||
/// The associated EVM contract address that the Cadence contract will bridge to | ||
access(all) let evmContractAddress: EVM.EVMAddress | ||
/// Whether the asset is Cadence- or EVM-native. Native here meaning the VM in which the | ||
/// asset is originally distributed. | ||
access(all) let nativeVM: VM | ||
|
||
init( | ||
cadenceType: Type, | ||
cadenceContractAddress: Address, | ||
evmContractAddress: EVM.EVMAddress, | ||
nativeVM: VM | ||
) { | ||
self.cadenceType = cadenceType | ||
self.cadenceContractAddress = cadenceContractAddress | ||
self.evmContractAddress = evmContractAddress | ||
self.nativeVM = nativeVM | ||
} | ||
} | ||
|
||
access(all) fun getEVMPointer(_ viewResolver: &{ViewResolver.Resolver}): EVMPointer? { | ||
if let view = viewResolver.resolveView(Type<EVMPointer>()) { | ||
if let v = view as? EVMPointer { | ||
return v | ||
} | ||
} | ||
return nil | ||
} | ||
|
||
/// View resolved at resource level denoting any metadata to be passed to the associated EVM | ||
/// contract at the time of bridging. This optional view would allow EVM side metadata to be | ||
/// updated based on current Cadence state. If the view is not supported, no bytes will be | ||
/// passed into EVM when bridging. | ||
/// | ||
access(all) struct EVMBytesMetadata { | ||
/// Returns the bytes to be passed to the EVM contract on `fulfillToEVM` call, allowing the | ||
/// EVM contract to update the metadata associated with the NFT. The corresponding Solidity | ||
/// `bytes` type allows the implementer greater flexibility by enabling them to pass | ||
/// arbitrary data between VMs. | ||
access(all) let bytes: EVM.EVMBytes | ||
|
||
init(bytes: EVM.EVMBytes) { | ||
self.bytes = bytes | ||
} | ||
} | ||
|
||
access(all) fun getEVMBytesMetadata(_ viewResolver: &{ViewResolver.Resolver}): EVMBytesMetadata? { | ||
if let view = viewResolver.resolveView(Type<EVMBytesMetadata>()) { | ||
if let v = view as? EVMBytesMetadata { | ||
return v | ||
} | ||
} | ||
return nil | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import "EVM" | ||
|
||
/// Returns the hex encoded address of the COA in the given Flow address | ||
/// | ||
access(all) fun main(flowAddress: Address): String? { | ||
return getAuthAccount<auth(BorrowValue) &Account>(flowAddress) | ||
.storage.borrow<&EVM.CadenceOwnedAccount>(from: /storage/evm) | ||
?.address() | ||
?.toString() | ||
?? nil | ||
} |
33 changes: 33 additions & 0 deletions
33
evm-bridging/cadence/scripts/get_underlying_erc721_address.cdc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
import "EVM" | ||
|
||
/// Returns the hex encoded address of the underlying ERC721 contract | ||
/// | ||
access(all) fun main(flowNftAddress: Address, wrapperERC721Address: String): String? { | ||
let coa = getAuthAccount<auth(BorrowValue) &Account>(flowNftAddress) | ||
.storage.borrow<auth(EVM.Call) &EVM.CadenceOwnedAccount>(from: /storage/evm) | ||
?? panic("No COA found in signer's account") | ||
|
||
return getUnderlyingERC721Address(coa, | ||
EVM.addressFromString(wrapperERC721Address) | ||
).toString() | ||
} | ||
|
||
/// Gets the underlying ERC721 address | ||
/// | ||
access(all) fun getUnderlyingERC721Address( | ||
_ coa: auth(EVM.Call) &EVM.CadenceOwnedAccount, | ||
_ wrapperAddress: EVM.EVMAddress | ||
): EVM.EVMAddress { | ||
let res = coa.call( | ||
to: wrapperAddress, | ||
data: EVM.encodeABIWithSignature("underlying()", []), | ||
gasLimit: 100_000, | ||
value: EVM.Balance(attoflow: 0) | ||
) | ||
|
||
assert(res.status == EVM.Status.successful, message: "Call to get underlying ERC721 address failed") | ||
let decodedResult = EVM.decodeABI(types: [Type<EVM.EVMAddress>()], data: res.data) | ||
assert(decodedResult.length == 1, message: "Invalid response length") | ||
|
||
return decodedResult[0] as! EVM.EVMAddress | ||
} |
Oops, something went wrong.