From 761c724438ddf8f7d2066f1b8805d02e5c5879de Mon Sep 17 00:00:00 2001
From: Giovanni Sanchez <108043524+sisyphusSmiling@users.noreply.github.com>
Date: Thu, 31 Oct 2024 14:01:23 -0600
Subject: [PATCH 01/20] forge install: random-coin-toss
---
.gitmodules | 3 +++
solidity/lib/random-coin-toss | 1 +
2 files changed, 4 insertions(+)
create mode 160000 solidity/lib/random-coin-toss
diff --git a/.gitmodules b/.gitmodules
index 0254bef..9af280a 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -7,3 +7,6 @@
[submodule "solidity/lib/forge-std"]
path = solidity/lib/forge-std
url = https://github.com/foundry-rs/forge-std
+[submodule "solidity/lib/random-coin-toss"]
+ path = solidity/lib/random-coin-toss
+ url = https://github.com/onflow/random-coin-toss
diff --git a/solidity/lib/random-coin-toss b/solidity/lib/random-coin-toss
new file mode 160000
index 0000000..8d47d83
--- /dev/null
+++ b/solidity/lib/random-coin-toss
@@ -0,0 +1 @@
+Subproject commit 8d47d83772f0f8e225cdc2cb8fc61706731b0712
From 9f2a8de17484ec25b16de6dfd31fa7c094d0c521 Mon Sep 17 00:00:00 2001
From: Giovanni Sanchez <108043524+sisyphusSmiling@users.noreply.github.com>
Date: Thu, 31 Oct 2024 14:30:48 -0600
Subject: [PATCH 02/20] remove submodule
---
.gitmodules | 5 +----
solidity/lib/random-coin-toss | 1 -
2 files changed, 1 insertion(+), 5 deletions(-)
delete mode 160000 solidity/lib/random-coin-toss
diff --git a/.gitmodules b/.gitmodules
index 9af280a..c4b9ae2 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -6,7 +6,4 @@
url = https://github.com/foundry-rs/forge-std
[submodule "solidity/lib/forge-std"]
path = solidity/lib/forge-std
- url = https://github.com/foundry-rs/forge-std
-[submodule "solidity/lib/random-coin-toss"]
- path = solidity/lib/random-coin-toss
- url = https://github.com/onflow/random-coin-toss
+ url = https://github.com/foundry-rs/forge-std
\ No newline at end of file
diff --git a/solidity/lib/random-coin-toss b/solidity/lib/random-coin-toss
deleted file mode 160000
index 8d47d83..0000000
--- a/solidity/lib/random-coin-toss
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit 8d47d83772f0f8e225cdc2cb8fc61706731b0712
From f0453d2fbd1b95925c73ac9ca8772ce906bbfce7 Mon Sep 17 00:00:00 2001
From: Giovanni Sanchez <108043524+sisyphusSmiling@users.noreply.github.com>
Date: Thu, 31 Oct 2024 14:30:55 -0600
Subject: [PATCH 03/20] forge install: random-coin-toss
---
.gitmodules | 5 ++++-
solidity/lib/random-coin-toss | 1 +
2 files changed, 5 insertions(+), 1 deletion(-)
create mode 160000 solidity/lib/random-coin-toss
diff --git a/.gitmodules b/.gitmodules
index c4b9ae2..9af280a 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -6,4 +6,7 @@
url = https://github.com/foundry-rs/forge-std
[submodule "solidity/lib/forge-std"]
path = solidity/lib/forge-std
- url = https://github.com/foundry-rs/forge-std
\ No newline at end of file
+ url = https://github.com/foundry-rs/forge-std
+[submodule "solidity/lib/random-coin-toss"]
+ path = solidity/lib/random-coin-toss
+ url = https://github.com/onflow/random-coin-toss
diff --git a/solidity/lib/random-coin-toss b/solidity/lib/random-coin-toss
new file mode 160000
index 0000000..8d47d83
--- /dev/null
+++ b/solidity/lib/random-coin-toss
@@ -0,0 +1 @@
+Subproject commit 8d47d83772f0f8e225cdc2cb8fc61706731b0712
From 8f6e417c3c32c9dd1d69a15adabaa33b5431e2d6 Mon Sep 17 00:00:00 2001
From: Giovanni Sanchez <108043524+sisyphusSmiling@users.noreply.github.com>
Date: Thu, 31 Oct 2024 17:07:21 -0600
Subject: [PATCH 04/20] update foundry.toml
---
foundry.toml | 1 +
1 file changed, 1 insertion(+)
diff --git a/foundry.toml b/foundry.toml
index 2b5e79b..755773f 100644
--- a/foundry.toml
+++ b/foundry.toml
@@ -4,5 +4,6 @@ out = "./solidity/out"
libs = ["./solidity/lib"]
script = "./solidity/script"
test = "./solidity/test"
+cache_path = "./solidity/cache"
# See more config options https://github.com/foundry-rs/foundry/blob/master/crates/config/README.md#all-options
From a37c4173018d18301ba145a25c3abba15549c4e2 Mon Sep 17 00:00:00 2001
From: Giovanni Sanchez <108043524+sisyphusSmiling@users.noreply.github.com>
Date: Thu, 31 Oct 2024 17:08:00 -0600
Subject: [PATCH 05/20] update foundry remappings
---
remappings.txt | 1 +
1 file changed, 1 insertion(+)
diff --git a/remappings.txt b/remappings.txt
index 6c3e85d..5776ef6 100644
--- a/remappings.txt
+++ b/remappings.txt
@@ -3,3 +3,4 @@ ds-test/=solidity/lib/forge-std/lib/ds-test/src/
erc4626-tests/=solidity/lib/openzeppelin-contracts/lib/erc4626-tests/
forge-std/=solidity/lib/forge-std/src/
openzeppelin-contracts/=solidity/lib/openzeppelin-contracts/
+onflow/random-coin-toss=solidity/lib/random-coin-toss
\ No newline at end of file
From 161e07b9da37163453dbaf9e11c2163c6dece430 Mon Sep 17 00:00:00 2001
From: Giovanni Sanchez <108043524+sisyphusSmiling@users.noreply.github.com>
Date: Fri, 1 Nov 2024 12:41:19 -0600
Subject: [PATCH 06/20] add CadenceArchUtils library & test coverage on random
mint
---
solidity/src/CadenceArchUtils.sol | 57 +++++++++++++++++++++++++++++
solidity/src/MaybeMintERC721.sol | 25 ++++++++++++-
solidity/test/MaybeMintERC721.t.sol | 31 +++++++++++++++-
3 files changed, 110 insertions(+), 3 deletions(-)
create mode 100644 solidity/src/CadenceArchUtils.sol
diff --git a/solidity/src/CadenceArchUtils.sol b/solidity/src/CadenceArchUtils.sol
new file mode 100644
index 0000000..e094395
--- /dev/null
+++ b/solidity/src/CadenceArchUtils.sol
@@ -0,0 +1,57 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.19;
+
+/**
+ * @dev This contract is a base contract to facilitate easier consumption of the Cadence Arch pre-compiles. Implementing
+ * contracts can use this contract to fetch the current Flow block height and fetch random numbers from the Cadence
+ * runtime.
+ */
+library CadenceArchUtils {
+ // Cadence Arch pre-compile address
+ address public constant cadenceArch = 0x0000000000000000000000010000000000000001;
+
+ /**
+ * @dev This method returns the current Flow block height.
+ *
+ * @return flowBlockHeight The current Flow block height.
+ */
+ function _flowBlockHeight() internal view returns (uint64) {
+ (bool ok, bytes memory data) = cadenceArch.staticcall(abi.encodeWithSignature("flowBlockHeight()"));
+ require(ok, "Unsuccessful call to Cadence Arch pre-compile when fetching Flow block height");
+
+ uint64 output = abi.decode(data, (uint64));
+ return output;
+ }
+
+ /**
+ * @dev This method uses the Cadence Arch pre-compiles to return a random number from the Cadence runtime. Consumers
+ * should know this is a revertible random source and should only be used as a source of randomness when called by
+ * trusted callers - i.e. with trust that the caller won't revert on result.
+ *
+ * @return randomSource The random source.
+ */
+ function _revertibleRandom() internal view returns (uint64) {
+ (bool ok, bytes memory data) = cadenceArch.staticcall(abi.encodeWithSignature("revertibleRandom()"));
+ require(ok, "Unsuccessful call to Cadence Arch pre-compile when fetching revertible random number");
+
+ uint64 output = abi.decode(data, (uint64));
+ return output;
+ }
+
+ /**
+ * @dev This method uses the Cadence Arch pre-compiles to returns a random source for a given Flow block height.
+ * The provided height must be at least one block in the past.
+ *
+ * @param flowHeight The Flow block height for which to get the random source.
+ * @return randomSource The random source for the given Flow block height.
+ */
+ function _getRandomSource(uint64 flowHeight) internal view returns (bytes32) {
+ (bool ok, bytes memory data) =
+ cadenceArch.staticcall(abi.encodeWithSignature("getRandomSource(uint64)", flowHeight));
+ require(ok, "Unsuccessful call to Cadence Arch pre-compile when fetching random source");
+
+ // Decode the result as bytes32 & return
+ bytes32 result = abi.decode(data, (bytes32));
+ return result;
+ }
+}
diff --git a/solidity/src/MaybeMintERC721.sol b/solidity/src/MaybeMintERC721.sol
index 0906222..fe1c981 100644
--- a/solidity/src/MaybeMintERC721.sol
+++ b/solidity/src/MaybeMintERC721.sol
@@ -3,6 +3,8 @@ pragma solidity 0.8.24;
import {ERC721} from "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
+import {CadenceArchUtils} from "./CadenceArchUtils.sol";
+// import {CadenceArchUtils} from "onflow/random-coin-toss/solidity/src/CadenceArchUtils.sol";
/**
* @title MaybeMintERC721
@@ -36,10 +38,29 @@ contract MaybeMintERC721 is ERC721, Ownable {
* to the beneficiary before minting the ERC721 to pay for mint
*/
function mint() external {
- // TODO: Get a random number to determine if the mint is successful
- // TODO: Set token URI
+ // Randomly fail mint with 50% chance of reverting
+ _maybeMint();
+ }
+
+ /**
+ * @dev Mint a new ERC721 token to the caller with some chance of failure.
+ * NOTE: Production systems using random minting should leverage a commit-reveal scheme
+ * to ensure that the random minting transaction cannot be reverted on random result.
+ */
+ function _maybeMint() internal {
+ _splitChanceRevert(); // randomly revert with 50% chance
+
totalSupply++; // increment the total supply
denomination.transferFrom(msg.sender, beneficiary, mintCost); // take payment for mint
_mint(msg.sender, totalSupply); // mint the token, assigning the next tokenId
+ // TODO: Set token URI
+ }
+
+ /**
+ * @dev Randomly revert with 50% chance
+ */
+ function _splitChanceRevert() internal view {
+ uint64 random = CadenceArchUtils._revertibleRandom();
+ require(random % 2 == 0, "No mint for you!");
}
}
diff --git a/solidity/test/MaybeMintERC721.t.sol b/solidity/test/MaybeMintERC721.t.sol
index b1b2f9d..b4b0694 100644
--- a/solidity/test/MaybeMintERC721.t.sol
+++ b/solidity/test/MaybeMintERC721.t.sol
@@ -8,6 +8,9 @@ import {MaybeMintERC721} from "../src/MaybeMintERC721.sol";
import {ExampleERC20} from "../src/test/ExampleERC20.sol";
contract MaybeMintERC721Test is Test {
+ // Cadence Arch pre-compile address used to get onchain revertible randomness
+ address private cadenceArch = 0x0000000000000000000000010000000000000001;
+
// Contracts
MaybeMintERC721 private erc721;
ExampleERC20 private erc20;
@@ -28,15 +31,41 @@ contract MaybeMintERC721Test is Test {
erc721 = new MaybeMintERC721(name, symbol, address(erc20), mintCost, beneficiary);
}
- function test_mint() public {
+ function testMintRandomEvenSucceeds() public {
erc20.mint(user, mintCost); // mint ERC20 to user
vm.prank(user);
erc20.approve(address(erc721), mintCost); // approve the ERC20 to be spent by MaybeMintERC721
+ // Mock the Cadence Arch precompile for revertibleRandom() call, returning 0 - mint should succeed
+ vm.mockCall(cadenceArch, abi.encodeWithSignature("revertibleRandom()"), abi.encode(uint64(0)));
+
vm.prank(user);
erc721.mint(); // mint ERC721 to user
assertEq(erc721.ownerOf(1), user); // user should own the ERC721 token
}
+
+ function testMintRandomOddFails() public {
+ erc20.mint(user, mintCost); // mint ERC20 to user
+
+ vm.prank(user);
+ erc20.approve(address(erc721), mintCost); // approve the ERC20 to be spent by MaybeMintERC721
+
+ // Mock the Cadence Arch precompile for revertibleRandom() call, returning 1 - mint should fail
+ vm.mockCall(cadenceArch, abi.encodeWithSignature("revertibleRandom()"), abi.encode(uint64(3)));
+
+ vm.prank(user);
+ vm.expectRevert("No mint for you!");
+ erc721.mint(); // Attempt to mint ERC721 to user - should revert
+ }
+
+ function testMintRandomWithoutApproveFails() public {
+ // Mock the Cadence Arch precompile for revertibleRandom() call, returning 0 - allows mint
+ vm.mockCall(cadenceArch, abi.encodeWithSignature("revertibleRandom()"), abi.encode(uint64(0)));
+
+ vm.prank(user);
+ vm.expectRevert();
+ erc721.mint(); // Attempt to mint ERC721 to user - reverts as user has not approved ERC20
+ }
}
From 5976256363ef9e57072559c3aa8613ab8a390bc9 Mon Sep 17 00:00:00 2001
From: Giovanni Sanchez <108043524+sisyphusSmiling@users.noreply.github.com>
Date: Fri, 1 Nov 2024 14:31:39 -0600
Subject: [PATCH 07/20] update dependencies
---
solidity/lib/openzeppelin-contracts | 2 +-
solidity/lib/random-coin-toss | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/solidity/lib/openzeppelin-contracts b/solidity/lib/openzeppelin-contracts
index 69c8def..448efee 160000
--- a/solidity/lib/openzeppelin-contracts
+++ b/solidity/lib/openzeppelin-contracts
@@ -1 +1 @@
-Subproject commit 69c8def5f222ff96f2b5beff05dfba996368aa79
+Subproject commit 448efeea6640bbbc09373f03fbc9c88e280147ba
diff --git a/solidity/lib/random-coin-toss b/solidity/lib/random-coin-toss
index 8d47d83..e82dee9 160000
--- a/solidity/lib/random-coin-toss
+++ b/solidity/lib/random-coin-toss
@@ -1 +1 @@
-Subproject commit 8d47d83772f0f8e225cdc2cb8fc61706731b0712
+Subproject commit e82dee9bab346049532ef0fd3574037f391e6428
From c73ef703353c6184f3c6a92316026d7d72a25d81 Mon Sep 17 00:00:00 2001
From: Giovanni Sanchez <108043524+sisyphusSmiling@users.noreply.github.com>
Date: Fri, 1 Nov 2024 14:46:13 -0600
Subject: [PATCH 08/20] replace local dep with foundry installed dep
---
solidity/src/CadenceArchUtils.sol | 57 -------------------------------
solidity/src/MaybeMintERC721.sol | 3 +-
2 files changed, 1 insertion(+), 59 deletions(-)
delete mode 100644 solidity/src/CadenceArchUtils.sol
diff --git a/solidity/src/CadenceArchUtils.sol b/solidity/src/CadenceArchUtils.sol
deleted file mode 100644
index e094395..0000000
--- a/solidity/src/CadenceArchUtils.sol
+++ /dev/null
@@ -1,57 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.19;
-
-/**
- * @dev This contract is a base contract to facilitate easier consumption of the Cadence Arch pre-compiles. Implementing
- * contracts can use this contract to fetch the current Flow block height and fetch random numbers from the Cadence
- * runtime.
- */
-library CadenceArchUtils {
- // Cadence Arch pre-compile address
- address public constant cadenceArch = 0x0000000000000000000000010000000000000001;
-
- /**
- * @dev This method returns the current Flow block height.
- *
- * @return flowBlockHeight The current Flow block height.
- */
- function _flowBlockHeight() internal view returns (uint64) {
- (bool ok, bytes memory data) = cadenceArch.staticcall(abi.encodeWithSignature("flowBlockHeight()"));
- require(ok, "Unsuccessful call to Cadence Arch pre-compile when fetching Flow block height");
-
- uint64 output = abi.decode(data, (uint64));
- return output;
- }
-
- /**
- * @dev This method uses the Cadence Arch pre-compiles to return a random number from the Cadence runtime. Consumers
- * should know this is a revertible random source and should only be used as a source of randomness when called by
- * trusted callers - i.e. with trust that the caller won't revert on result.
- *
- * @return randomSource The random source.
- */
- function _revertibleRandom() internal view returns (uint64) {
- (bool ok, bytes memory data) = cadenceArch.staticcall(abi.encodeWithSignature("revertibleRandom()"));
- require(ok, "Unsuccessful call to Cadence Arch pre-compile when fetching revertible random number");
-
- uint64 output = abi.decode(data, (uint64));
- return output;
- }
-
- /**
- * @dev This method uses the Cadence Arch pre-compiles to returns a random source for a given Flow block height.
- * The provided height must be at least one block in the past.
- *
- * @param flowHeight The Flow block height for which to get the random source.
- * @return randomSource The random source for the given Flow block height.
- */
- function _getRandomSource(uint64 flowHeight) internal view returns (bytes32) {
- (bool ok, bytes memory data) =
- cadenceArch.staticcall(abi.encodeWithSignature("getRandomSource(uint64)", flowHeight));
- require(ok, "Unsuccessful call to Cadence Arch pre-compile when fetching random source");
-
- // Decode the result as bytes32 & return
- bytes32 result = abi.decode(data, (bytes32));
- return result;
- }
-}
diff --git a/solidity/src/MaybeMintERC721.sol b/solidity/src/MaybeMintERC721.sol
index fe1c981..47c0620 100644
--- a/solidity/src/MaybeMintERC721.sol
+++ b/solidity/src/MaybeMintERC721.sol
@@ -3,8 +3,7 @@ pragma solidity 0.8.24;
import {ERC721} from "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
-import {CadenceArchUtils} from "./CadenceArchUtils.sol";
-// import {CadenceArchUtils} from "onflow/random-coin-toss/solidity/src/CadenceArchUtils.sol";
+import {CadenceArchUtils} from "onflow/random-coin-toss/solidity/src/CadenceArchUtils.sol";
/**
* @title MaybeMintERC721
From aa01cbb9dc80d91d5a0330a1a6f429a20d740a22 Mon Sep 17 00:00:00 2001
From: Giovanni Sanchez <108043524+sisyphusSmiling@users.noreply.github.com>
Date: Mon, 4 Nov 2024 11:33:48 -0700
Subject: [PATCH 09/20] add custom errors to ERC721
---
solidity/src/MaybeMintERC721.sol | 19 +-
solidity/src/test/WETH9.sol | 756 ++++++++++++++++++++++++++++
solidity/test/MaybeMintERC721.t.sol | 5 +-
3 files changed, 773 insertions(+), 7 deletions(-)
create mode 100644 solidity/src/test/WETH9.sol
diff --git a/solidity/src/MaybeMintERC721.sol b/solidity/src/MaybeMintERC721.sol
index 47c0620..3d98c1a 100644
--- a/solidity/src/MaybeMintERC721.sol
+++ b/solidity/src/MaybeMintERC721.sol
@@ -17,6 +17,9 @@ contract MaybeMintERC721 is ERC721, Ownable {
address public beneficiary;
uint256 public totalSupply;
+ error RandomRevert();
+ error InsufficientAllowance(address denomination, address sender, uint256 needed);
+
constructor(string memory _name, string memory _symbol, address _erc20, uint256 _mintCost, address _beneficiary)
ERC721(_name, _symbol)
Ownable(msg.sender)
@@ -49,10 +52,14 @@ contract MaybeMintERC721 is ERC721, Ownable {
function _maybeMint() internal {
_splitChanceRevert(); // randomly revert with 50% chance
- totalSupply++; // increment the total supply
- denomination.transferFrom(msg.sender, beneficiary, mintCost); // take payment for mint
- _mint(msg.sender, totalSupply); // mint the token, assigning the next tokenId
- // TODO: Set token URI
+ // take payment for mint
+ try denomination.transferFrom(msg.sender, beneficiary, mintCost) {
+ totalSupply++; // increment the total supply
+ _mint(msg.sender, totalSupply); // mint the token, assigning the next tokenId
+ // TODO: Set token URI
+ } catch {
+ revert InsufficientAllowance(address(denomination), msg.sender, mintCost);
+ }
}
/**
@@ -60,6 +67,8 @@ contract MaybeMintERC721 is ERC721, Ownable {
*/
function _splitChanceRevert() internal view {
uint64 random = CadenceArchUtils._revertibleRandom();
- require(random % 2 == 0, "No mint for you!");
+ if (random % 2 == 1) {
+ revert RandomRevert();
+ }
}
}
diff --git a/solidity/src/test/WETH9.sol b/solidity/src/test/WETH9.sol
new file mode 100644
index 0000000..a592dc0
--- /dev/null
+++ b/solidity/src/test/WETH9.sol
@@ -0,0 +1,756 @@
+// Copyright (C) 2015, 2016, 2017 Dapphub
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+pragma solidity >=0.4.22 <0.6;
+
+contract WETH9 {
+ string public name = "Wrapped Flow";
+ string public symbol = "WFLOW";
+ uint8 public decimals = 18;
+
+ event Approval(address indexed src, address indexed guy, uint wad);
+ event Transfer(address indexed src, address indexed dst, uint wad);
+ event Deposit(address indexed dst, uint wad);
+ event Withdrawal(address indexed src, uint wad);
+
+ mapping (address => uint) public balanceOf;
+ mapping (address => mapping (address => uint)) public allowance;
+
+ function() external payable {
+ deposit();
+ }
+ function deposit() public payable {
+ balanceOf[msg.sender] += msg.value;
+ emit Deposit(msg.sender, msg.value);
+ }
+ function withdraw(uint wad) public {
+ require(balanceOf[msg.sender] >= wad);
+ balanceOf[msg.sender] -= wad;
+ msg.sender.transfer(wad);
+ emit Withdrawal(msg.sender, wad);
+ }
+
+ function totalSupply() public view returns (uint) {
+ return address(this).balance;
+ }
+
+ function approve(address guy, uint wad) public returns (bool) {
+ allowance[msg.sender][guy] = wad;
+ emit Approval(msg.sender, guy, wad);
+ return true;
+ }
+
+ function transfer(address dst, uint wad) public returns (bool) {
+ return transferFrom(msg.sender, dst, wad);
+ }
+
+ function transferFrom(address src, address dst, uint wad)
+ public
+ returns (bool)
+ {
+ require(balanceOf[src] >= wad);
+
+ if (src != msg.sender && allowance[src][msg.sender] != uint(-1)) {
+ require(allowance[src][msg.sender] >= wad);
+ allowance[src][msg.sender] -= wad;
+ }
+
+ balanceOf[src] -= wad;
+ balanceOf[dst] += wad;
+
+ emit Transfer(src, dst, wad);
+
+ return true;
+ }
+}
+
+
+/*
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+
+ Copyright (C)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ Copyright (C)
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+.
+
+ The GNU General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License. But first, please read
+.
+
+*/
\ No newline at end of file
diff --git a/solidity/test/MaybeMintERC721.t.sol b/solidity/test/MaybeMintERC721.t.sol
index b4b0694..ef9bc03 100644
--- a/solidity/test/MaybeMintERC721.t.sol
+++ b/solidity/test/MaybeMintERC721.t.sol
@@ -56,7 +56,7 @@ contract MaybeMintERC721Test is Test {
vm.mockCall(cadenceArch, abi.encodeWithSignature("revertibleRandom()"), abi.encode(uint64(3)));
vm.prank(user);
- vm.expectRevert("No mint for you!");
+ vm.expectRevert(bytes4(keccak256("RandomRevert()")));
erc721.mint(); // Attempt to mint ERC721 to user - should revert
}
@@ -64,8 +64,9 @@ contract MaybeMintERC721Test is Test {
// Mock the Cadence Arch precompile for revertibleRandom() call, returning 0 - allows mint
vm.mockCall(cadenceArch, abi.encodeWithSignature("revertibleRandom()"), abi.encode(uint64(0)));
+ bytes4 errSelector = bytes4(keccak256("InsufficientAllowance(address,address,uint256)"));
vm.prank(user);
- vm.expectRevert();
+ vm.expectRevert(abi.encodeWithSelector(errSelector, address(erc20), user, mintCost));
erc721.mint(); // Attempt to mint ERC721 to user - reverts as user has not approved ERC20
}
}
From 6ded160cb91e412bbf07a1ae1585804560c8056f Mon Sep 17 00:00:00 2001
From: Giovanni Sanchez <108043524+sisyphusSmiling@users.noreply.github.com>
Date: Mon, 4 Nov 2024 16:19:10 -0700
Subject: [PATCH 10/20] add bundled Cadence txn
---
.../transactions/bundled/wrap_and_mint.cdc | 126 ++++++++++++++++++
1 file changed, 126 insertions(+)
create mode 100644 cadence/transactions/bundled/wrap_and_mint.cdc
diff --git a/cadence/transactions/bundled/wrap_and_mint.cdc b/cadence/transactions/bundled/wrap_and_mint.cdc
new file mode 100644
index 0000000..38e07b6
--- /dev/null
+++ b/cadence/transactions/bundled/wrap_and_mint.cdc
@@ -0,0 +1,126 @@
+import "FungibleToken"
+import "FlowToken"
+import "EVM"
+
+/// This transaction wraps FLOW as WFLOW, approves an ERC721 contract to move the mint amount, and attempts to mint an
+/// ERC721 token. The transaction is reverted if any of the EVM interactions fail
+///
+transaction(wflowAddressHex: String, maybeMintERC721AddressHex: String) {
+
+ let coa: auth(EVM.Call) &EVM.CadenceOwnedAccount
+ let mintCost: UFix64
+ let wflowAddress: EVM.EVMAddress
+ let erc721Address: EVM.EVMAddress
+
+ prepare(signer: auth(SaveValue, BorrowValue, IssueStorageCapabilityController, PublishCapability, UnpublishCapability) &Account) {
+ /* COA configuration & assigment */
+ //
+ let storagePath = /storage/evm
+ let publicPath = /public/evm
+ // Configure a COA if one is not found in storage at the default path
+ if signer.storage.type(at: storagePath) == nil {
+ // Create & save the CadenceOwnedAccount (COA) Resource
+ let newCOA <- EVM.createCadenceOwnedAccount()
+ signer.storage.save(<-newCOA, to: storagePath)
+
+ // Unpublish any existing Capability at the public path if it exists
+ signer.capabilities.unpublish(publicPath)
+ // Issue & publish the public, unentitled COA Capability
+ let coaCapability = signer.capabilities.storage.issue<&EVM.CadenceOwnedAccount>(storagePath)
+ signer.capabilities.publish(coaCapability, at: publicPath)
+ }
+
+ // Assign the COA reference to the transaction's coa field
+ self.coa = signer.storage.borrow(from: storagePath)
+ ?? panic("A CadenceOwnedAccount (COA) Resource could not be found at path ".concat(storagePath.toString())
+ .concat(" - ensure the COA Resource is created and saved at this path to enable EVM interactions"))
+
+ /* Fund COA with cost of mint */
+ //
+ // Borrow authorized reference to signer's FlowToken Vault
+ let sourceVault = signer.storage.borrow(
+ from: /storage/flowTokenVault
+ ) ?? panic("The signer does not store a FlowToken Vault object at the path "
+ .concat("/storage/flowTokenVault. ")
+ .concat("The signer must initialize their account with this vault first!"))
+ // Withdraw from the signer's FlowToken Vault
+ self.mintCost = 1.0
+ let fundingVault <- sourceVault.withdraw(amount: self.mintCost) as! @FlowToken.Vault
+ // Deposit the mint cost into the COA
+ self.coa.deposit(from: <-fundingVault)
+
+ /* Set the WFLOW contract address */
+ //
+ // View the cannonical WFLOW contract at:
+ // https://evm-testnet.flowscan.io/address/0xd3bF53DAC106A0290B0483EcBC89d40FcC961f3e
+ self.wflowAddress = EVM.addressFromString(wflowAddressHex)
+
+ /* Assign the ERC721 EVM Address */
+ //
+ // Deserialize the provided ERC721 hex string to an EVM address
+ self.erc721Address = EVM.addressFromString(maybeMintERC721AddressHex)
+ }
+
+ pre {
+ self.coa.balance().inFLOW() >= self.mintCost:
+ "CadenceOwnedAccount holds insufficient FLOW balance to mint - "
+ .concat("Ensure COA has at least ".concat(self.mintCost.toString()).concat(" FLOW"))
+ }
+
+ execute {
+ /* Wrap FLOW in EVM as WFLOW */
+ //
+ // Encode calldata & set value
+ let depositCalldata = EVM.encodeABIWithSignature("deposit()", [])
+ let value = EVM.Balance(attoflow: 0)
+ value.setFLOW(flow: self.mintCost)
+ // Call the WFLOW contract, wrapping the sent FLOW
+ let wrapResult = self.coa.call(
+ to: self.wflowAddress,
+ data: depositCalldata,
+ gasLimit: 15_000_000,
+ value: value
+ )
+ assert(
+ wrapResult.status == EVM.Status.successful,
+ message: "Wrapping FLOW as WFLOW failed: ".concat(wrapResult.errorMessage)
+ )
+
+ /* Approve the ERC721 address for the mint amount */
+ //
+ // Encode calldata approve(address,uint) calldata, providing the ERC721 address & mint amount
+ let approveCalldata = EVM.encodeABIWithSignature(
+ "approve(address,uint256)",
+ [self.erc721Address, UInt256(1_000_000_000_000_000_000)]
+ )
+ // Call the WFLOW contract, approving the ERC721 address to move the mint amount
+ let approveResult = self.coa.call(
+ to: self.wflowAddress,
+ data: approveCalldata,
+ gasLimit: 15_000_000,
+ value: EVM.Balance(attoflow: 0)
+ )
+ assert(
+ approveResult.status == EVM.Status.successful,
+ message: "Approving ERC721 address on WFLOW contract failed: ".concat(approveResult.errorMessage)
+ )
+
+ /* Attempt to mint ERC721 */
+ //
+ // Encode the mint() calldata
+ let mintCalldata = EVM.encodeABIWithSignature("mint()", [])
+ // Call the ERC721 contract, attempting to mint
+ let mintResult = self.coa.call(
+ to: self.erc721Address,
+ data: mintCalldata,
+ gasLimit: 15_000_000,
+ value: EVM.Balance(attoflow: 0)
+ )
+ // If mint fails, all other actions in this transaction are reverted
+ assert(
+ mintResult.status == EVM.Status.successful,
+ message: "Minting ERC721 token failed: ".concat(mintResult.errorMessage)
+ )
+ }
+}
+
\ No newline at end of file
From 54b4550bc49547390036633db592544e8dc96dcb Mon Sep 17 00:00:00 2001
From: Giovanni Sanchez <108043524+sisyphusSmiling@users.noreply.github.com>
Date: Mon, 4 Nov 2024 16:28:55 -0700
Subject: [PATCH 11/20] add stepwise Cadence txns
---
.../transactions/stepwise/0_create_coa.cdc | 62 +++++++++++++++++
cadence/transactions/stepwise/1_wrap_flow.cdc | 68 +++++++++++++++++++
cadence/transactions/stepwise/2_approve.cdc | 66 ++++++++++++++++++
cadence/transactions/stepwise/3_mint.cdc | 46 +++++++++++++
4 files changed, 242 insertions(+)
create mode 100644 cadence/transactions/stepwise/0_create_coa.cdc
create mode 100644 cadence/transactions/stepwise/1_wrap_flow.cdc
create mode 100644 cadence/transactions/stepwise/2_approve.cdc
create mode 100644 cadence/transactions/stepwise/3_mint.cdc
diff --git a/cadence/transactions/stepwise/0_create_coa.cdc b/cadence/transactions/stepwise/0_create_coa.cdc
new file mode 100644
index 0000000..77f8575
--- /dev/null
+++ b/cadence/transactions/stepwise/0_create_coa.cdc
@@ -0,0 +1,62 @@
+import "FungibleToken"
+import "FlowToken"
+import "EVM"
+
+/// Creates a CadenceOwnedAccount & funds with the specified amount. If the COA already exists, the transaction reverts.
+///
+transaction(amount: UFix64) {
+
+ let coa: auth(EVM.Call) &EVM.CadenceOwnedAccount
+ let fundingVault: @FlowToken.Vault
+
+ prepare(signer: auth(SaveValue, BorrowValue, IssueStorageCapabilityController, PublishCapability, UnpublishCapability) &Account) {
+ pre {
+ amount > 0.0: "The funding amount must be greater than zero"
+ }
+ /* COA configuration & assigment */
+ //
+ let storagePath = /storage/evm
+ let publicPath = /public/evm
+ // Configure a COA if one is not found in storage at the default path
+ if signer.storage.type(at: storagePath) != nil {
+ panic("CadenceOwnedAccount already exists at path ".concat(storagePath.toString()))
+ }
+ // Create & save the CadenceOwnedAccount (COA) Resource
+ let newCOA <- EVM.createCadenceOwnedAccount()
+ signer.storage.save(<-newCOA, to: storagePath)
+
+ // Unpublish any existing Capability at the public path if it exists
+ signer.capabilities.unpublish(publicPath)
+ // Issue & publish the public, unentitled COA Capability
+ let coaCapability = signer.capabilities.storage.issue<&EVM.CadenceOwnedAccount>(storagePath)
+ signer.capabilities.publish(coaCapability, at: publicPath)
+
+ // Assign the COA reference to the transaction's coa field
+ self.coa = signer.storage.borrow(from: storagePath)
+ ?? panic("A CadenceOwnedAccount (COA) Resource could not be found at path ".concat(storagePath.toString())
+ .concat(" - ensure the COA Resource is created and saved at this path to enable EVM interactions"))
+
+ // Borrow authorized reference to signer's FlowToken Vault
+ let sourceVault = signer.storage.borrow(
+ from: /storage/flowTokenVault
+ ) ?? panic("The signer does not store a FlowToken Vault object at the path "
+ .concat("/storage/flowTokenVault. ")
+ .concat("The signer must initialize their account with this vault first!"))
+ // Withdraw from the signer's FlowToken Vault
+ self.fundingVault <- sourceVault.withdraw(amount: amount) as! @FlowToken.Vault
+ }
+
+ pre {
+ self.fundingVault.balance == amount:
+ "Expected amount =".concat(amount.toString())
+ .concat(" but fundingVault.balance=").concat(self.fundingVault.balance.toString())
+ }
+
+ execute {
+ /* Fund COA */
+ //
+ // Deposit the FLOW into the COA
+ self.coa.deposit(from: <-self.fundingVault)
+ }
+}
+
\ No newline at end of file
diff --git a/cadence/transactions/stepwise/1_wrap_flow.cdc b/cadence/transactions/stepwise/1_wrap_flow.cdc
new file mode 100644
index 0000000..ab19d56
--- /dev/null
+++ b/cadence/transactions/stepwise/1_wrap_flow.cdc
@@ -0,0 +1,68 @@
+import "FungibleToken"
+import "FlowToken"
+import "EVM"
+
+/// This transaction wraps FLOW as WFLOW, funing the signer's CadenceOwnedAccount with the mint cost
+///
+transaction(wflowAddressHex: String) {
+
+ let coa: auth(EVM.Call) &EVM.CadenceOwnedAccount
+ let mintCost: UFix64
+ let wflowAddress: EVM.EVMAddress
+
+ prepare(signer: auth(SaveValue, BorrowValue) &Account) {
+ /* COA configuration & assigment */
+ //
+ let storagePath = /storage/evm
+ // Assign the COA reference to the transaction's coa field
+ self.coa = signer.storage.borrow(from: storagePath)
+ ?? panic("A CadenceOwnedAccount (COA) Resource could not be found at path ".concat(storagePath.toString())
+ .concat(" - ensure the COA Resource is created and saved at this path to enable EVM interactions"))
+
+ /* Fund COA with cost of mint */
+ //
+ // Borrow authorized reference to signer's FlowToken Vault
+ let sourceVault = signer.storage.borrow(
+ from: /storage/flowTokenVault
+ ) ?? panic("The signer does not store a FlowToken Vault object at the path "
+ .concat("/storage/flowTokenVault. ")
+ .concat("The signer must initialize their account with this vault first!"))
+ // Withdraw from the signer's FlowToken Vault
+ self.mintCost = 1.0
+ let fundingVault <- sourceVault.withdraw(amount: self.mintCost) as! @FlowToken.Vault
+ // Deposit the mint cost into the COA
+ self.coa.deposit(from: <-fundingVault)
+
+ /* Set the WFLOW contract address */
+ //
+ // View the cannonical WFLOW contract at:
+ // https://evm-testnet.flowscan.io/address/0xd3bF53DAC106A0290B0483EcBC89d40FcC961f3e
+ self.wflowAddress = EVM.addressFromString(wflowAddressHex)
+ }
+
+ pre {
+ self.coa.balance().inFLOW() >= self.mintCost:
+ "CadenceOwnedAccount holds insufficient FLOW balance to mint - "
+ .concat("Ensure COA has at least ".concat(self.mintCost.toString()).concat(" FLOW"))
+ }
+
+ execute {
+ /* Wrap FLOW in EVM as WFLOW */
+ //
+ // Encode calldata & set value
+ let depositCalldata = EVM.encodeABIWithSignature("deposit()", [])
+ let value = EVM.Balance(attoflow: 0)
+ value.setFLOW(flow: self.mintCost)
+ // Call the WFLOW contract, wrapping the sent FLOW
+ let wrapResult = self.coa.call(
+ to: self.wflowAddress,
+ data: depositCalldata,
+ gasLimit: 15_000_000,
+ value: value
+ )
+ assert(
+ wrapResult.status == EVM.Status.successful,
+ message: "Wrapping FLOW as WFLOW failed: ".concat(wrapResult.errorMessage)
+ )
+ }
+}
diff --git a/cadence/transactions/stepwise/2_approve.cdc b/cadence/transactions/stepwise/2_approve.cdc
new file mode 100644
index 0000000..02865dc
--- /dev/null
+++ b/cadence/transactions/stepwise/2_approve.cdc
@@ -0,0 +1,66 @@
+import "FungibleToken"
+import "FlowToken"
+import "EVM"
+
+/// This transaction wraps FLOW as WFLOW, approves an ERC721 contract to move the mint amount, and attempts to mint an
+/// ERC721 token. The transaction is reverted if any of the EVM interactions fail
+///
+transaction(wflowAddressHex: String, maybeMintERC721AddressHex: String) {
+
+ let coa: auth(EVM.Call) &EVM.CadenceOwnedAccount
+ let mintCost: UFix64
+ let wflowAddress: EVM.EVMAddress
+ let erc721Address: EVM.EVMAddress
+
+ prepare(signer: auth(SaveValue, BorrowValue) &Account) {
+ /* COA assignment */
+ //
+ let storagePath = /storage/evm
+ // Assign the COA reference to the transaction's coa field
+ self.coa = signer.storage.borrow(from: storagePath)
+ ?? panic("A CadenceOwnedAccount (COA) Resource could not be found at path ".concat(storagePath.toString())
+ .concat(" - ensure the COA Resource is created and saved at this path to enable EVM interactions"))
+
+ /* Fund COA with cost of mint */
+ //
+ self.mintCost = 1.0
+ /* Set the WFLOW contract address */
+ //
+ // View the cannonical WFLOW contract at:
+ // https://evm-testnet.flowscan.io/address/0xd3bF53DAC106A0290B0483EcBC89d40FcC961f3e
+ self.wflowAddress = EVM.addressFromString(wflowAddressHex)
+
+ /* Assign the ERC721 EVM Address */
+ //
+ // Deserialize the provided ERC721 hex string to an EVM address
+ self.erc721Address = EVM.addressFromString(maybeMintERC721AddressHex)
+ }
+
+ pre {
+ self.coa.balance().inFLOW() >= self.mintCost:
+ "CadenceOwnedAccount holds insufficient FLOW balance to mint - "
+ .concat("Ensure COA has at least ".concat(self.mintCost.toString()).concat(" FLOW"))
+ }
+
+ execute {
+ /* Approve the ERC721 address for the mint amount */
+ //
+ // Encode calldata approve(address,uint) calldata, providing the ERC721 address & mint amount
+ let approveCalldata = EVM.encodeABIWithSignature(
+ "approve(address,uint256)",
+ [self.erc721Address, UInt256(1_000_000_000_000_000_000)]
+ )
+ // Call the WFLOW contract, approving the ERC721 address to move the mint amount
+ let approveResult = self.coa.call(
+ to: self.wflowAddress,
+ data: approveCalldata,
+ gasLimit: 15_000_000,
+ value: EVM.Balance(attoflow: 0)
+ )
+ assert(
+ approveResult.status == EVM.Status.successful,
+ message: "Approving ERC721 address on WFLOW contract failed: ".concat(approveResult.errorMessage)
+ )
+ }
+}
+
\ No newline at end of file
diff --git a/cadence/transactions/stepwise/3_mint.cdc b/cadence/transactions/stepwise/3_mint.cdc
new file mode 100644
index 0000000..70bf04d
--- /dev/null
+++ b/cadence/transactions/stepwise/3_mint.cdc
@@ -0,0 +1,46 @@
+import "FungibleToken"
+import "FlowToken"
+import "EVM"
+
+/// This transaction attempts to mint the ERC721 token, reverting if the mint fails
+///
+transaction(wflowAddressHex: String, maybeMintERC721AddressHex: String) {
+
+ let coa: auth(EVM.Call) &EVM.CadenceOwnedAccount
+ let erc721Address: EVM.EVMAddress
+
+ prepare(signer: auth(SaveValue, BorrowValue, IssueStorageCapabilityController, PublishCapability, UnpublishCapability) &Account) {
+ /* COA assigment */
+ //
+ let storagePath = /storage/evm
+
+ // Assign the COA reference to the transaction's coa field
+ self.coa = signer.storage.borrow(from: storagePath)
+ ?? panic("A CadenceOwnedAccount (COA) Resource could not be found at path ".concat(storagePath.toString())
+ .concat(" - ensure the COA Resource is created and saved at this path to enable EVM interactions"))
+
+ /* Assign the ERC721 EVM Address */
+ //
+ // Deserialize the provided ERC721 hex string to an EVM address
+ self.erc721Address = EVM.addressFromString(maybeMintERC721AddressHex)
+ }
+
+ execute {
+ /* Attempt to mint ERC721 */
+ //
+ // Encode the mint() calldata
+ let mintCalldata = EVM.encodeABIWithSignature("mint()", [])
+ // Call the ERC721 contract, attempting to mint
+ let mintResult = self.coa.call(
+ to: self.erc721Address,
+ data: mintCalldata,
+ gasLimit: 15_000_000,
+ value: EVM.Balance(attoflow: 0)
+ )
+ // If mint fails, all other actions in this transaction are reverted
+ assert(
+ mintResult.status == EVM.Status.successful,
+ message: "Minting ERC721 token failed: ".concat(mintResult.errorMessage)
+ )
+ }
+}
From 26f071e6bff00fb7ca6e2a91269b08cb79ce39ef Mon Sep 17 00:00:00 2001
From: Giovanni Sanchez <108043524+sisyphusSmiling@users.noreply.github.com>
Date: Mon, 4 Nov 2024 16:29:56 -0700
Subject: [PATCH 12/20] remove unused GitHub cadence tests workflow
---
.github/workflows/cadence_test.yml | 30 ------------------------------
1 file changed, 30 deletions(-)
delete mode 100644 .github/workflows/cadence_test.yml
diff --git a/.github/workflows/cadence_test.yml b/.github/workflows/cadence_test.yml
deleted file mode 100644
index a3b0c18..0000000
--- a/.github/workflows/cadence_test.yml
+++ /dev/null
@@ -1,30 +0,0 @@
-name: CI
-
-on: pull_request
-
-jobs:
- tests:
- name: Flow CLI Tests
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v3
- - name: Set up Go
- uses: actions/setup-go@v3
- with:
- go-version: "1.20.x"
- - uses: actions/cache@v1
- with:
- path: ~/go/pkg/mod
- key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
- restore-keys: |
- ${{ runner.os }}-go-
- - name: Install Flow CLI
- run: sh -ci "$(curl -fsSL https://raw.githubusercontent.com/onflow/flow-cli/master/install.sh)"
- - name: Flow CLI Version
- run: flow version
- - name: Update PATH
- run: echo "/root/.local/bin" >> $GITHUB_PATH
- - name: Install dependencies
- run: flow deps install
- - name: Run tests
- run: flow test --cover --covercode="contracts" --coverprofile="coverage.lcov" cadence/tests/*.cdc
From 71206e8f3ce8c5b23b4963c6d8243681819d9cd1 Mon Sep 17 00:00:00 2001
From: Giovanni Sanchez <108043524+sisyphusSmiling@users.noreply.github.com>
Date: Mon, 4 Nov 2024 17:31:41 -0700
Subject: [PATCH 13/20] remove WETH9 contract
---
solidity/src/test/WETH9.sol | 756 ------------------------------------
1 file changed, 756 deletions(-)
delete mode 100644 solidity/src/test/WETH9.sol
diff --git a/solidity/src/test/WETH9.sol b/solidity/src/test/WETH9.sol
deleted file mode 100644
index a592dc0..0000000
--- a/solidity/src/test/WETH9.sol
+++ /dev/null
@@ -1,756 +0,0 @@
-// Copyright (C) 2015, 2016, 2017 Dapphub
-
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with this program. If not, see .
-
-pragma solidity >=0.4.22 <0.6;
-
-contract WETH9 {
- string public name = "Wrapped Flow";
- string public symbol = "WFLOW";
- uint8 public decimals = 18;
-
- event Approval(address indexed src, address indexed guy, uint wad);
- event Transfer(address indexed src, address indexed dst, uint wad);
- event Deposit(address indexed dst, uint wad);
- event Withdrawal(address indexed src, uint wad);
-
- mapping (address => uint) public balanceOf;
- mapping (address => mapping (address => uint)) public allowance;
-
- function() external payable {
- deposit();
- }
- function deposit() public payable {
- balanceOf[msg.sender] += msg.value;
- emit Deposit(msg.sender, msg.value);
- }
- function withdraw(uint wad) public {
- require(balanceOf[msg.sender] >= wad);
- balanceOf[msg.sender] -= wad;
- msg.sender.transfer(wad);
- emit Withdrawal(msg.sender, wad);
- }
-
- function totalSupply() public view returns (uint) {
- return address(this).balance;
- }
-
- function approve(address guy, uint wad) public returns (bool) {
- allowance[msg.sender][guy] = wad;
- emit Approval(msg.sender, guy, wad);
- return true;
- }
-
- function transfer(address dst, uint wad) public returns (bool) {
- return transferFrom(msg.sender, dst, wad);
- }
-
- function transferFrom(address src, address dst, uint wad)
- public
- returns (bool)
- {
- require(balanceOf[src] >= wad);
-
- if (src != msg.sender && allowance[src][msg.sender] != uint(-1)) {
- require(allowance[src][msg.sender] >= wad);
- allowance[src][msg.sender] -= wad;
- }
-
- balanceOf[src] -= wad;
- balanceOf[dst] += wad;
-
- emit Transfer(src, dst, wad);
-
- return true;
- }
-}
-
-
-/*
- GNU GENERAL PUBLIC LICENSE
- Version 3, 29 June 2007
-
- Copyright (C) 2007 Free Software Foundation, Inc.
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
- Preamble
-
- The GNU General Public License is a free, copyleft license for
-software and other kinds of works.
-
- The licenses for most software and other practical works are designed
-to take away your freedom to share and change the works. By contrast,
-the GNU General Public License is intended to guarantee your freedom to
-share and change all versions of a program--to make sure it remains free
-software for all its users. We, the Free Software Foundation, use the
-GNU General Public License for most of our software; it applies also to
-any other work released this way by its authors. You can apply it to
-your programs, too.
-
- When we speak of free software, we are referring to freedom, not
-price. Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-them if you wish), that you receive source code or can get it if you
-want it, that you can change the software or use pieces of it in new
-free programs, and that you know you can do these things.
-
- To protect your rights, we need to prevent others from denying you
-these rights or asking you to surrender the rights. Therefore, you have
-certain responsibilities if you distribute copies of the software, or if
-you modify it: responsibilities to respect the freedom of others.
-
- For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must pass on to the recipients the same
-freedoms that you received. You must make sure that they, too, receive
-or can get the source code. And you must show them these terms so they
-know their rights.
-
- Developers that use the GNU GPL protect your rights with two steps:
-(1) assert copyright on the software, and (2) offer you this License
-giving you legal permission to copy, distribute and/or modify it.
-
- For the developers' and authors' protection, the GPL clearly explains
-that there is no warranty for this free software. For both users' and
-authors' sake, the GPL requires that modified versions be marked as
-changed, so that their problems will not be attributed erroneously to
-authors of previous versions.
-
- Some devices are designed to deny users access to install or run
-modified versions of the software inside them, although the manufacturer
-can do so. This is fundamentally incompatible with the aim of
-protecting users' freedom to change the software. The systematic
-pattern of such abuse occurs in the area of products for individuals to
-use, which is precisely where it is most unacceptable. Therefore, we
-have designed this version of the GPL to prohibit the practice for those
-products. If such problems arise substantially in other domains, we
-stand ready to extend this provision to those domains in future versions
-of the GPL, as needed to protect the freedom of users.
-
- Finally, every program is threatened constantly by software patents.
-States should not allow patents to restrict development and use of
-software on general-purpose computers, but in those that do, we wish to
-avoid the special danger that patents applied to a free program could
-make it effectively proprietary. To prevent this, the GPL assures that
-patents cannot be used to render the program non-free.
-
- The precise terms and conditions for copying, distribution and
-modification follow.
-
- TERMS AND CONDITIONS
-
- 0. Definitions.
-
- "This License" refers to version 3 of the GNU General Public License.
-
- "Copyright" also means copyright-like laws that apply to other kinds of
-works, such as semiconductor masks.
-
- "The Program" refers to any copyrightable work licensed under this
-License. Each licensee is addressed as "you". "Licensees" and
-"recipients" may be individuals or organizations.
-
- To "modify" a work means to copy from or adapt all or part of the work
-in a fashion requiring copyright permission, other than the making of an
-exact copy. The resulting work is called a "modified version" of the
-earlier work or a work "based on" the earlier work.
-
- A "covered work" means either the unmodified Program or a work based
-on the Program.
-
- To "propagate" a work means to do anything with it that, without
-permission, would make you directly or secondarily liable for
-infringement under applicable copyright law, except executing it on a
-computer or modifying a private copy. Propagation includes copying,
-distribution (with or without modification), making available to the
-public, and in some countries other activities as well.
-
- To "convey" a work means any kind of propagation that enables other
-parties to make or receive copies. Mere interaction with a user through
-a computer network, with no transfer of a copy, is not conveying.
-
- An interactive user interface displays "Appropriate Legal Notices"
-to the extent that it includes a convenient and prominently visible
-feature that (1) displays an appropriate copyright notice, and (2)
-tells the user that there is no warranty for the work (except to the
-extent that warranties are provided), that licensees may convey the
-work under this License, and how to view a copy of this License. If
-the interface presents a list of user commands or options, such as a
-menu, a prominent item in the list meets this criterion.
-
- 1. Source Code.
-
- The "source code" for a work means the preferred form of the work
-for making modifications to it. "Object code" means any non-source
-form of a work.
-
- A "Standard Interface" means an interface that either is an official
-standard defined by a recognized standards body, or, in the case of
-interfaces specified for a particular programming language, one that
-is widely used among developers working in that language.
-
- The "System Libraries" of an executable work include anything, other
-than the work as a whole, that (a) is included in the normal form of
-packaging a Major Component, but which is not part of that Major
-Component, and (b) serves only to enable use of the work with that
-Major Component, or to implement a Standard Interface for which an
-implementation is available to the public in source code form. A
-"Major Component", in this context, means a major essential component
-(kernel, window system, and so on) of the specific operating system
-(if any) on which the executable work runs, or a compiler used to
-produce the work, or an object code interpreter used to run it.
-
- The "Corresponding Source" for a work in object code form means all
-the source code needed to generate, install, and (for an executable
-work) run the object code and to modify the work, including scripts to
-control those activities. However, it does not include the work's
-System Libraries, or general-purpose tools or generally available free
-programs which are used unmodified in performing those activities but
-which are not part of the work. For example, Corresponding Source
-includes interface definition files associated with source files for
-the work, and the source code for shared libraries and dynamically
-linked subprograms that the work is specifically designed to require,
-such as by intimate data communication or control flow between those
-subprograms and other parts of the work.
-
- The Corresponding Source need not include anything that users
-can regenerate automatically from other parts of the Corresponding
-Source.
-
- The Corresponding Source for a work in source code form is that
-same work.
-
- 2. Basic Permissions.
-
- All rights granted under this License are granted for the term of
-copyright on the Program, and are irrevocable provided the stated
-conditions are met. This License explicitly affirms your unlimited
-permission to run the unmodified Program. The output from running a
-covered work is covered by this License only if the output, given its
-content, constitutes a covered work. This License acknowledges your
-rights of fair use or other equivalent, as provided by copyright law.
-
- You may make, run and propagate covered works that you do not
-convey, without conditions so long as your license otherwise remains
-in force. You may convey covered works to others for the sole purpose
-of having them make modifications exclusively for you, or provide you
-with facilities for running those works, provided that you comply with
-the terms of this License in conveying all material for which you do
-not control copyright. Those thus making or running the covered works
-for you must do so exclusively on your behalf, under your direction
-and control, on terms that prohibit them from making any copies of
-your copyrighted material outside their relationship with you.
-
- Conveying under any other circumstances is permitted solely under
-the conditions stated below. Sublicensing is not allowed; section 10
-makes it unnecessary.
-
- 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
-
- No covered work shall be deemed part of an effective technological
-measure under any applicable law fulfilling obligations under article
-11 of the WIPO copyright treaty adopted on 20 December 1996, or
-similar laws prohibiting or restricting circumvention of such
-measures.
-
- When you convey a covered work, you waive any legal power to forbid
-circumvention of technological measures to the extent such circumvention
-is effected by exercising rights under this License with respect to
-the covered work, and you disclaim any intention to limit operation or
-modification of the work as a means of enforcing, against the work's
-users, your or third parties' legal rights to forbid circumvention of
-technological measures.
-
- 4. Conveying Verbatim Copies.
-
- You may convey verbatim copies of the Program's source code as you
-receive it, in any medium, provided that you conspicuously and
-appropriately publish on each copy an appropriate copyright notice;
-keep intact all notices stating that this License and any
-non-permissive terms added in accord with section 7 apply to the code;
-keep intact all notices of the absence of any warranty; and give all
-recipients a copy of this License along with the Program.
-
- You may charge any price or no price for each copy that you convey,
-and you may offer support or warranty protection for a fee.
-
- 5. Conveying Modified Source Versions.
-
- You may convey a work based on the Program, or the modifications to
-produce it from the Program, in the form of source code under the
-terms of section 4, provided that you also meet all of these conditions:
-
- a) The work must carry prominent notices stating that you modified
- it, and giving a relevant date.
-
- b) The work must carry prominent notices stating that it is
- released under this License and any conditions added under section
- 7. This requirement modifies the requirement in section 4 to
- "keep intact all notices".
-
- c) You must license the entire work, as a whole, under this
- License to anyone who comes into possession of a copy. This
- License will therefore apply, along with any applicable section 7
- additional terms, to the whole of the work, and all its parts,
- regardless of how they are packaged. This License gives no
- permission to license the work in any other way, but it does not
- invalidate such permission if you have separately received it.
-
- d) If the work has interactive user interfaces, each must display
- Appropriate Legal Notices; however, if the Program has interactive
- interfaces that do not display Appropriate Legal Notices, your
- work need not make them do so.
-
- A compilation of a covered work with other separate and independent
-works, which are not by their nature extensions of the covered work,
-and which are not combined with it such as to form a larger program,
-in or on a volume of a storage or distribution medium, is called an
-"aggregate" if the compilation and its resulting copyright are not
-used to limit the access or legal rights of the compilation's users
-beyond what the individual works permit. Inclusion of a covered work
-in an aggregate does not cause this License to apply to the other
-parts of the aggregate.
-
- 6. Conveying Non-Source Forms.
-
- You may convey a covered work in object code form under the terms
-of sections 4 and 5, provided that you also convey the
-machine-readable Corresponding Source under the terms of this License,
-in one of these ways:
-
- a) Convey the object code in, or embodied in, a physical product
- (including a physical distribution medium), accompanied by the
- Corresponding Source fixed on a durable physical medium
- customarily used for software interchange.
-
- b) Convey the object code in, or embodied in, a physical product
- (including a physical distribution medium), accompanied by a
- written offer, valid for at least three years and valid for as
- long as you offer spare parts or customer support for that product
- model, to give anyone who possesses the object code either (1) a
- copy of the Corresponding Source for all the software in the
- product that is covered by this License, on a durable physical
- medium customarily used for software interchange, for a price no
- more than your reasonable cost of physically performing this
- conveying of source, or (2) access to copy the
- Corresponding Source from a network server at no charge.
-
- c) Convey individual copies of the object code with a copy of the
- written offer to provide the Corresponding Source. This
- alternative is allowed only occasionally and noncommercially, and
- only if you received the object code with such an offer, in accord
- with subsection 6b.
-
- d) Convey the object code by offering access from a designated
- place (gratis or for a charge), and offer equivalent access to the
- Corresponding Source in the same way through the same place at no
- further charge. You need not require recipients to copy the
- Corresponding Source along with the object code. If the place to
- copy the object code is a network server, the Corresponding Source
- may be on a different server (operated by you or a third party)
- that supports equivalent copying facilities, provided you maintain
- clear directions next to the object code saying where to find the
- Corresponding Source. Regardless of what server hosts the
- Corresponding Source, you remain obligated to ensure that it is
- available for as long as needed to satisfy these requirements.
-
- e) Convey the object code using peer-to-peer transmission, provided
- you inform other peers where the object code and Corresponding
- Source of the work are being offered to the general public at no
- charge under subsection 6d.
-
- A separable portion of the object code, whose source code is excluded
-from the Corresponding Source as a System Library, need not be
-included in conveying the object code work.
-
- A "User Product" is either (1) a "consumer product", which means any
-tangible personal property which is normally used for personal, family,
-or household purposes, or (2) anything designed or sold for incorporation
-into a dwelling. In determining whether a product is a consumer product,
-doubtful cases shall be resolved in favor of coverage. For a particular
-product received by a particular user, "normally used" refers to a
-typical or common use of that class of product, regardless of the status
-of the particular user or of the way in which the particular user
-actually uses, or expects or is expected to use, the product. A product
-is a consumer product regardless of whether the product has substantial
-commercial, industrial or non-consumer uses, unless such uses represent
-the only significant mode of use of the product.
-
- "Installation Information" for a User Product means any methods,
-procedures, authorization keys, or other information required to install
-and execute modified versions of a covered work in that User Product from
-a modified version of its Corresponding Source. The information must
-suffice to ensure that the continued functioning of the modified object
-code is in no case prevented or interfered with solely because
-modification has been made.
-
- If you convey an object code work under this section in, or with, or
-specifically for use in, a User Product, and the conveying occurs as
-part of a transaction in which the right of possession and use of the
-User Product is transferred to the recipient in perpetuity or for a
-fixed term (regardless of how the transaction is characterized), the
-Corresponding Source conveyed under this section must be accompanied
-by the Installation Information. But this requirement does not apply
-if neither you nor any third party retains the ability to install
-modified object code on the User Product (for example, the work has
-been installed in ROM).
-
- The requirement to provide Installation Information does not include a
-requirement to continue to provide support service, warranty, or updates
-for a work that has been modified or installed by the recipient, or for
-the User Product in which it has been modified or installed. Access to a
-network may be denied when the modification itself materially and
-adversely affects the operation of the network or violates the rules and
-protocols for communication across the network.
-
- Corresponding Source conveyed, and Installation Information provided,
-in accord with this section must be in a format that is publicly
-documented (and with an implementation available to the public in
-source code form), and must require no special password or key for
-unpacking, reading or copying.
-
- 7. Additional Terms.
-
- "Additional permissions" are terms that supplement the terms of this
-License by making exceptions from one or more of its conditions.
-Additional permissions that are applicable to the entire Program shall
-be treated as though they were included in this License, to the extent
-that they are valid under applicable law. If additional permissions
-apply only to part of the Program, that part may be used separately
-under those permissions, but the entire Program remains governed by
-this License without regard to the additional permissions.
-
- When you convey a copy of a covered work, you may at your option
-remove any additional permissions from that copy, or from any part of
-it. (Additional permissions may be written to require their own
-removal in certain cases when you modify the work.) You may place
-additional permissions on material, added by you to a covered work,
-for which you have or can give appropriate copyright permission.
-
- Notwithstanding any other provision of this License, for material you
-add to a covered work, you may (if authorized by the copyright holders of
-that material) supplement the terms of this License with terms:
-
- a) Disclaiming warranty or limiting liability differently from the
- terms of sections 15 and 16 of this License; or
-
- b) Requiring preservation of specified reasonable legal notices or
- author attributions in that material or in the Appropriate Legal
- Notices displayed by works containing it; or
-
- c) Prohibiting misrepresentation of the origin of that material, or
- requiring that modified versions of such material be marked in
- reasonable ways as different from the original version; or
-
- d) Limiting the use for publicity purposes of names of licensors or
- authors of the material; or
-
- e) Declining to grant rights under trademark law for use of some
- trade names, trademarks, or service marks; or
-
- f) Requiring indemnification of licensors and authors of that
- material by anyone who conveys the material (or modified versions of
- it) with contractual assumptions of liability to the recipient, for
- any liability that these contractual assumptions directly impose on
- those licensors and authors.
-
- All other non-permissive additional terms are considered "further
-restrictions" within the meaning of section 10. If the Program as you
-received it, or any part of it, contains a notice stating that it is
-governed by this License along with a term that is a further
-restriction, you may remove that term. If a license document contains
-a further restriction but permits relicensing or conveying under this
-License, you may add to a covered work material governed by the terms
-of that license document, provided that the further restriction does
-not survive such relicensing or conveying.
-
- If you add terms to a covered work in accord with this section, you
-must place, in the relevant source files, a statement of the
-additional terms that apply to those files, or a notice indicating
-where to find the applicable terms.
-
- Additional terms, permissive or non-permissive, may be stated in the
-form of a separately written license, or stated as exceptions;
-the above requirements apply either way.
-
- 8. Termination.
-
- You may not propagate or modify a covered work except as expressly
-provided under this License. Any attempt otherwise to propagate or
-modify it is void, and will automatically terminate your rights under
-this License (including any patent licenses granted under the third
-paragraph of section 11).
-
- However, if you cease all violation of this License, then your
-license from a particular copyright holder is reinstated (a)
-provisionally, unless and until the copyright holder explicitly and
-finally terminates your license, and (b) permanently, if the copyright
-holder fails to notify you of the violation by some reasonable means
-prior to 60 days after the cessation.
-
- Moreover, your license from a particular copyright holder is
-reinstated permanently if the copyright holder notifies you of the
-violation by some reasonable means, this is the first time you have
-received notice of violation of this License (for any work) from that
-copyright holder, and you cure the violation prior to 30 days after
-your receipt of the notice.
-
- Termination of your rights under this section does not terminate the
-licenses of parties who have received copies or rights from you under
-this License. If your rights have been terminated and not permanently
-reinstated, you do not qualify to receive new licenses for the same
-material under section 10.
-
- 9. Acceptance Not Required for Having Copies.
-
- You are not required to accept this License in order to receive or
-run a copy of the Program. Ancillary propagation of a covered work
-occurring solely as a consequence of using peer-to-peer transmission
-to receive a copy likewise does not require acceptance. However,
-nothing other than this License grants you permission to propagate or
-modify any covered work. These actions infringe copyright if you do
-not accept this License. Therefore, by modifying or propagating a
-covered work, you indicate your acceptance of this License to do so.
-
- 10. Automatic Licensing of Downstream Recipients.
-
- Each time you convey a covered work, the recipient automatically
-receives a license from the original licensors, to run, modify and
-propagate that work, subject to this License. You are not responsible
-for enforcing compliance by third parties with this License.
-
- An "entity transaction" is a transaction transferring control of an
-organization, or substantially all assets of one, or subdividing an
-organization, or merging organizations. If propagation of a covered
-work results from an entity transaction, each party to that
-transaction who receives a copy of the work also receives whatever
-licenses to the work the party's predecessor in interest had or could
-give under the previous paragraph, plus a right to possession of the
-Corresponding Source of the work from the predecessor in interest, if
-the predecessor has it or can get it with reasonable efforts.
-
- You may not impose any further restrictions on the exercise of the
-rights granted or affirmed under this License. For example, you may
-not impose a license fee, royalty, or other charge for exercise of
-rights granted under this License, and you may not initiate litigation
-(including a cross-claim or counterclaim in a lawsuit) alleging that
-any patent claim is infringed by making, using, selling, offering for
-sale, or importing the Program or any portion of it.
-
- 11. Patents.
-
- A "contributor" is a copyright holder who authorizes use under this
-License of the Program or a work on which the Program is based. The
-work thus licensed is called the contributor's "contributor version".
-
- A contributor's "essential patent claims" are all patent claims
-owned or controlled by the contributor, whether already acquired or
-hereafter acquired, that would be infringed by some manner, permitted
-by this License, of making, using, or selling its contributor version,
-but do not include claims that would be infringed only as a
-consequence of further modification of the contributor version. For
-purposes of this definition, "control" includes the right to grant
-patent sublicenses in a manner consistent with the requirements of
-this License.
-
- Each contributor grants you a non-exclusive, worldwide, royalty-free
-patent license under the contributor's essential patent claims, to
-make, use, sell, offer for sale, import and otherwise run, modify and
-propagate the contents of its contributor version.
-
- In the following three paragraphs, a "patent license" is any express
-agreement or commitment, however denominated, not to enforce a patent
-(such as an express permission to practice a patent or covenant not to
-sue for patent infringement). To "grant" such a patent license to a
-party means to make such an agreement or commitment not to enforce a
-patent against the party.
-
- If you convey a covered work, knowingly relying on a patent license,
-and the Corresponding Source of the work is not available for anyone
-to copy, free of charge and under the terms of this License, through a
-publicly available network server or other readily accessible means,
-then you must either (1) cause the Corresponding Source to be so
-available, or (2) arrange to deprive yourself of the benefit of the
-patent license for this particular work, or (3) arrange, in a manner
-consistent with the requirements of this License, to extend the patent
-license to downstream recipients. "Knowingly relying" means you have
-actual knowledge that, but for the patent license, your conveying the
-covered work in a country, or your recipient's use of the covered work
-in a country, would infringe one or more identifiable patents in that
-country that you have reason to believe are valid.
-
- If, pursuant to or in connection with a single transaction or
-arrangement, you convey, or propagate by procuring conveyance of, a
-covered work, and grant a patent license to some of the parties
-receiving the covered work authorizing them to use, propagate, modify
-or convey a specific copy of the covered work, then the patent license
-you grant is automatically extended to all recipients of the covered
-work and works based on it.
-
- A patent license is "discriminatory" if it does not include within
-the scope of its coverage, prohibits the exercise of, or is
-conditioned on the non-exercise of one or more of the rights that are
-specifically granted under this License. You may not convey a covered
-work if you are a party to an arrangement with a third party that is
-in the business of distributing software, under which you make payment
-to the third party based on the extent of your activity of conveying
-the work, and under which the third party grants, to any of the
-parties who would receive the covered work from you, a discriminatory
-patent license (a) in connection with copies of the covered work
-conveyed by you (or copies made from those copies), or (b) primarily
-for and in connection with specific products or compilations that
-contain the covered work, unless you entered into that arrangement,
-or that patent license was granted, prior to 28 March 2007.
-
- Nothing in this License shall be construed as excluding or limiting
-any implied license or other defenses to infringement that may
-otherwise be available to you under applicable patent law.
-
- 12. No Surrender of Others' Freedom.
-
- If conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot convey a
-covered work so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you may
-not convey it at all. For example, if you agree to terms that obligate you
-to collect a royalty for further conveying from those to whom you convey
-the Program, the only way you could satisfy both those terms and this
-License would be to refrain entirely from conveying the Program.
-
- 13. Use with the GNU Affero General Public License.
-
- Notwithstanding any other provision of this License, you have
-permission to link or combine any covered work with a work licensed
-under version 3 of the GNU Affero General Public License into a single
-combined work, and to convey the resulting work. The terms of this
-License will continue to apply to the part which is the covered work,
-but the special requirements of the GNU Affero General Public License,
-section 13, concerning interaction through a network will apply to the
-combination as such.
-
- 14. Revised Versions of this License.
-
- The Free Software Foundation may publish revised and/or new versions of
-the GNU General Public License from time to time. Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
- Each version is given a distinguishing version number. If the
-Program specifies that a certain numbered version of the GNU General
-Public License "or any later version" applies to it, you have the
-option of following the terms and conditions either of that numbered
-version or of any later version published by the Free Software
-Foundation. If the Program does not specify a version number of the
-GNU General Public License, you may choose any version ever published
-by the Free Software Foundation.
-
- If the Program specifies that a proxy can decide which future
-versions of the GNU General Public License can be used, that proxy's
-public statement of acceptance of a version permanently authorizes you
-to choose that version for the Program.
-
- Later license versions may give you additional or different
-permissions. However, no additional obligations are imposed on any
-author or copyright holder as a result of your choosing to follow a
-later version.
-
- 15. Disclaimer of Warranty.
-
- THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
-APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
-HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
-OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
-THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
-IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
-ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
-
- 16. Limitation of Liability.
-
- IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
-THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
-GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
-USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
-DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
-PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
-EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGES.
-
- 17. Interpretation of Sections 15 and 16.
-
- If the disclaimer of warranty and limitation of liability provided
-above cannot be given local legal effect according to their terms,
-reviewing courts shall apply local law that most closely approximates
-an absolute waiver of all civil liability in connection with the
-Program, unless a warranty or assumption of liability accompanies a
-copy of the Program in return for a fee.
-
- END OF TERMS AND CONDITIONS
-
- How to Apply These Terms to Your New Programs
-
- If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
- To do so, attach the following notices to the program. It is safest
-to attach them to the start of each source file to most effectively
-state the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
-
- Copyright (C)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see .
-
-Also add information on how to contact you by electronic and paper mail.
-
- If the program does terminal interaction, make it output a short
-notice like this when it starts in an interactive mode:
-
- Copyright (C)
- This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
- This is free software, and you are welcome to redistribute it
- under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License. Of course, your program's commands
-might be different; for a GUI interface, you would use an "about box".
-
- You should also get your employer (if you work as a programmer) or school,
-if any, to sign a "copyright disclaimer" for the program, if necessary.
-For more information on this, and how to apply and follow the GNU GPL, see
-.
-
- The GNU General Public License does not permit incorporating your program
-into proprietary programs. If your program is a subroutine library, you
-may consider it more useful to permit linking proprietary applications with
-the library. If this is what you want to do, use the GNU Lesser General
-Public License instead of this License. But first, please read
-.
-
-*/
\ No newline at end of file
From 9dba454aa2c35d8a450ba6c5e30deef37d1b1d1c Mon Sep 17 00:00:00 2001
From: Giovanni Sanchez <108043524+sisyphusSmiling@users.noreply.github.com>
Date: Mon, 4 Nov 2024 17:58:32 -0700
Subject: [PATCH 14/20] update transaction comments
---
cadence/transactions/bundled/wrap_and_mint.cdc | 18 ++++++++++++++++--
cadence/transactions/stepwise/0_create_coa.cdc | 5 ++++-
cadence/transactions/stepwise/1_wrap_flow.cdc | 11 ++++++++++-
cadence/transactions/stepwise/2_approve.cdc | 10 ++++++++--
cadence/transactions/stepwise/3_mint.cdc | 11 ++++++++++-
5 files changed, 48 insertions(+), 7 deletions(-)
diff --git a/cadence/transactions/bundled/wrap_and_mint.cdc b/cadence/transactions/bundled/wrap_and_mint.cdc
index 38e07b6..9424816 100644
--- a/cadence/transactions/bundled/wrap_and_mint.cdc
+++ b/cadence/transactions/bundled/wrap_and_mint.cdc
@@ -2,8 +2,22 @@ import "FungibleToken"
import "FlowToken"
import "EVM"
-/// This transaction wraps FLOW as WFLOW, approves an ERC721 contract to move the mint amount, and attempts to mint an
-/// ERC721 token. The transaction is reverted if any of the EVM interactions fail
+/// This transaction demonstrates how multiple EVM calls can be batched in a single Cadence transaction via
+/// CadenceOwnedAccount (COA), performing the following actions:
+///
+/// 1. Configures a COA in the signer's account if needed
+/// 2. Funds the signer's COA with enough FLOW to cover the WFLOW cost of minting an ERC721 token
+/// 3. Wraps FLOW as WFLOW - EVM call 1
+/// 4. Approves the example MaybeMintERC721 contract which accepts WFLOW to move the mint amount - EVM call 2
+/// 5. Attempts to mint an ERC721 token - EVM call 3
+///
+/// Importantly, the transaction is reverted if any of the EVM interactions fail returning the account to the original
+/// state before the transaction was executed across Cadence & EVM.
+///
+/// For more context, see https://github.com/onflow/batched-evm-exec-example
+///
+/// @param wflowAddressHex: The EVM address hex of the WFLOW contract as a String
+/// @param maybeMintERC721AddressHex: The EVM address hex of the ERC721 contract as a String
///
transaction(wflowAddressHex: String, maybeMintERC721AddressHex: String) {
diff --git a/cadence/transactions/stepwise/0_create_coa.cdc b/cadence/transactions/stepwise/0_create_coa.cdc
index 77f8575..daced72 100644
--- a/cadence/transactions/stepwise/0_create_coa.cdc
+++ b/cadence/transactions/stepwise/0_create_coa.cdc
@@ -2,7 +2,10 @@ import "FungibleToken"
import "FlowToken"
import "EVM"
-/// Creates a CadenceOwnedAccount & funds with the specified amount. If the COA already exists, the transaction reverts.
+/// Creates a CadenceOwnedAccount (COA) & funds with the specified amount.
+/// If a COA already exists in storage at /storage/evm, the transaction reverts.
+///
+/// @param amount: The amount of FLOW to fund the COA with, sourcing funds from the signer's FlowToken Vault
///
transaction(amount: UFix64) {
diff --git a/cadence/transactions/stepwise/1_wrap_flow.cdc b/cadence/transactions/stepwise/1_wrap_flow.cdc
index ab19d56..00a6534 100644
--- a/cadence/transactions/stepwise/1_wrap_flow.cdc
+++ b/cadence/transactions/stepwise/1_wrap_flow.cdc
@@ -2,7 +2,16 @@ import "FungibleToken"
import "FlowToken"
import "EVM"
-/// This transaction wraps FLOW as WFLOW, funing the signer's CadenceOwnedAccount with the mint cost
+/// This transaction wraps FLOW as WFLOW, sourcing the wrapped FLOW from the signer's FlowToken Vault in the amount of
+/// 1.0 FLOW to cover the mint cost of 1 MaybeMintERC721 token. If a CadenceOwnedAccount (COA) is not configured in the
+/// signer's account, one is configured, allowing the Flow account to interact with Flow's EVM runtime.
+///
+/// While not interesting on its own, this transaction demonstrates a single step in the bundled EVM execution example,
+/// showcasing how Cadence can be used to atomically orchestrate multiple EVM interactions in a single transaction.
+///
+/// For more context, see https://github.com/onflow/batched-evm-exec-example
+///
+/// @param wflowAddressHex: The EVM address hex of the WFLOW contract as a String
///
transaction(wflowAddressHex: String) {
diff --git a/cadence/transactions/stepwise/2_approve.cdc b/cadence/transactions/stepwise/2_approve.cdc
index 02865dc..61338f0 100644
--- a/cadence/transactions/stepwise/2_approve.cdc
+++ b/cadence/transactions/stepwise/2_approve.cdc
@@ -2,8 +2,14 @@ import "FungibleToken"
import "FlowToken"
import "EVM"
-/// This transaction wraps FLOW as WFLOW, approves an ERC721 contract to move the mint amount, and attempts to mint an
-/// ERC721 token. The transaction is reverted if any of the EVM interactions fail
+/// This transaction approves the provided ERC721 address to move the mint amount on the WFLOW contract. In this example
+/// the mint amount is 1.0 WFLOW. While not included in the code below, this transaction is part of a larger example
+/// showcasing how Cadence can be used to atomically orchestrate multiple EVM interactions in a single transaction.
+///
+/// For more context, see https://github.com/onflow/batched-evm-exec-example
+///
+/// @param wflowAddressHex: The EVM address hex of the WFLOW contract as a String
+/// @param maybeMintERC721AddressHex: The EVM address hex of the ERC721 contract as a String
///
transaction(wflowAddressHex: String, maybeMintERC721AddressHex: String) {
diff --git a/cadence/transactions/stepwise/3_mint.cdc b/cadence/transactions/stepwise/3_mint.cdc
index 70bf04d..3bd5504 100644
--- a/cadence/transactions/stepwise/3_mint.cdc
+++ b/cadence/transactions/stepwise/3_mint.cdc
@@ -2,7 +2,16 @@ import "FungibleToken"
import "FlowToken"
import "EVM"
-/// This transaction attempts to mint the ERC721 token, reverting if the mint fails
+/// This transaction attempts to mint the ERC721 token, reverting if the mint fails. The intended example is part of a
+/// larger example showcasing how Cadence can be used to atomically orchestrate multiple EVM interactions in a single
+/// transaction. In this case, the MaybeMintERC721 contract mints an ERC721 token in exchange for WFLOW with a 50%
+/// probability of success. If the mint fails, the transaction can be reverted, ensuring the account is returned to the
+/// original state before the transaction was executed across Cadence & EVM.
+///
+/// For more context, see https://github.com/onflow/batched-evm-exec-example
+///
+/// @param wflowAddressHex: The EVM address hex of the WFLOW contract as a String
+/// @param maybeMintERC721AddressHex: The EVM address hex of the ERC721 contract as a String
///
transaction(wflowAddressHex: String, maybeMintERC721AddressHex: String) {
From ee2030825b191a4e25f3ce928ead70eb21664b35 Mon Sep 17 00:00:00 2001
From: Giovanni Sanchez <108043524+sisyphusSmiling@users.noreply.github.com>
Date: Mon, 4 Nov 2024 18:12:31 -0700
Subject: [PATCH 15/20] update README with testnet deployments
---
README.md | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)
diff --git a/README.md b/README.md
index fbec104..8752613 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,14 @@
-### Batched Cadence EVM Execution Example
+# Batched Cadence EVM Execution Example
> This repo contains an example of how to batch EVM execution on Flow using Cadence.
-:building_construction: WIP
+:building_construction: Currently work in progress.
+
+## Deployments
+
+The relevant contracts can be found at the following addresses on Flow Testnet:
+
+|Contract|Address|
+|---|---|
+|`MaybeMintERC72`|[`0xdbC43Ba45381e02825b14322cDdd15eC4B3164E6`](https://evm-testnet.flowscan.io/address/0xdbc43ba45381e02825b14322cddd15ec4b3164e6?tab=contract_code)|
+|`WFLOW`|[`0xd3bF53DAC106A0290B0483EcBC89d40FcC961f3e`](https://evm-testnet.flowscan.io/token/0xd3bF53DAC106A0290B0483EcBC89d40FcC961f3e?tab=contract_code)|
From 0975463f488125c201f39cfd1dd8f5bfa113379f Mon Sep 17 00:00:00 2001
From: Giovanni Sanchez <108043524+sisyphusSmiling@users.noreply.github.com>
Date: Thu, 7 Nov 2024 13:37:50 -0700
Subject: [PATCH 16/20] remove onflow/random-coin-toss
---
.gitmodules | 3 ---
solidity/lib/random-coin-toss | 1 -
2 files changed, 4 deletions(-)
delete mode 160000 solidity/lib/random-coin-toss
diff --git a/.gitmodules b/.gitmodules
index 9af280a..0254bef 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -7,6 +7,3 @@
[submodule "solidity/lib/forge-std"]
path = solidity/lib/forge-std
url = https://github.com/foundry-rs/forge-std
-[submodule "solidity/lib/random-coin-toss"]
- path = solidity/lib/random-coin-toss
- url = https://github.com/onflow/random-coin-toss
diff --git a/solidity/lib/random-coin-toss b/solidity/lib/random-coin-toss
deleted file mode 160000
index e82dee9..0000000
--- a/solidity/lib/random-coin-toss
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit e82dee9bab346049532ef0fd3574037f391e6428
From f5fa952df104520bacb3fe2ed1dc4a6ac7e29536 Mon Sep 17 00:00:00 2001
From: Giovanni Sanchez <108043524+sisyphusSmiling@users.noreply.github.com>
Date: Thu, 7 Nov 2024 14:00:29 -0700
Subject: [PATCH 17/20] add Cadence tests & helper solidity contract
---
cadence/tests/evm_revertible_random_tests.cdc | 64 ++++++++++++
.../tests/scripts/evm_revertible_random.cdc | 16 +++
cadence/tests/test_helpers.cdc | 44 +++++++++
cadence/tests/transactions/create_coa.cdc | 51 ++++++++++
cadence/tests/transactions/deploy.cdc | 56 +++++++++++
cadence/tests/transactions/move_block.cdc | 19 ++++
cadence/tests/wrap_and_mint_tests.cdc | 99 +++++++++++++++++++
.../src/test/TestCadenceRandomConsumer.sol | 29 ++++++
8 files changed, 378 insertions(+)
create mode 100644 cadence/tests/evm_revertible_random_tests.cdc
create mode 100644 cadence/tests/scripts/evm_revertible_random.cdc
create mode 100644 cadence/tests/test_helpers.cdc
create mode 100644 cadence/tests/transactions/create_coa.cdc
create mode 100644 cadence/tests/transactions/deploy.cdc
create mode 100644 cadence/tests/transactions/move_block.cdc
create mode 100644 cadence/tests/wrap_and_mint_tests.cdc
create mode 100644 solidity/src/test/TestCadenceRandomConsumer.sol
diff --git a/cadence/tests/evm_revertible_random_tests.cdc b/cadence/tests/evm_revertible_random_tests.cdc
new file mode 100644
index 0000000..8ae3dac
--- /dev/null
+++ b/cadence/tests/evm_revertible_random_tests.cdc
@@ -0,0 +1,64 @@
+import Test
+import BlockchainHelpers
+import "test_helpers.cdc"
+
+import "EVM"
+
+access(all) let serviceAccount = Test.serviceAccount()
+
+access(all) var coaAddress: String = ""
+access(all) var testAddress: String = ""
+
+access(all)
+fun setup() {
+ // Create & fund a CadenceOwnedAccount
+ let coaRes = executeTransaction(
+ "./transactions/create_coa.cdc",
+ [100.0],
+ serviceAccount
+ )
+ Test.expect(coaRes, Test.beSucceeded())
+
+ // Extract COA address from event
+ let coaEvts = Test.eventsOfType(Type())
+ let coaEvt = coaEvts[0] as! EVM.CadenceOwnedAccountCreated
+ coaAddress = coaEvt.address
+ log("COA address: ".concat(coaAddress))
+
+ // Deploy WFLOW
+ let testDeployRes = executeTransaction(
+ "./transactions/deploy.cdc",
+ [testBytecode, UInt64(15_000_000), 0.0],
+ serviceAccount
+ )
+ Test.expect(testDeployRes, Test.beSucceeded())
+
+ // Extract test address from event
+ var txnExecEvts = Test.eventsOfType(Type())
+ let testEvt = txnExecEvts[2] as! EVM.TransactionExecuted
+ testAddress = testEvt.contractAddress
+
+ log("Test address: ".concat(testAddress))
+}
+
+access(all)
+fun testGetRevertibleRandomSucceeds() {
+ let a = getEVMRevertibleRandom(coaHost: serviceAccount.address, testAddress: EVM.addressFromString(testAddress))
+ moveBlock()
+ let b = getEVMRevertibleRandom(coaHost: serviceAccount.address, testAddress: EVM.addressFromString(testAddress))
+ moveBlock()
+ let c = getEVMRevertibleRandom(coaHost: serviceAccount.address, testAddress: EVM.addressFromString(testAddress))
+ moveBlock()
+ let d = getEVMRevertibleRandom(coaHost: serviceAccount.address, testAddress: EVM.addressFromString(testAddress))
+ moveBlock()
+ let e = getEVMRevertibleRandom(coaHost: serviceAccount.address, testAddress: EVM.addressFromString(testAddress))
+ moveBlock()
+ let f = getEVMRevertibleRandom(coaHost: serviceAccount.address, testAddress: EVM.addressFromString(testAddress))
+ log(String.join([a.toString(), b.toString(), c.toString(), d.toString(), e.toString(), f.toString()], separator: ", "))
+ // Test.assert(a != b || a != c || b != c, message: "getEVMRevertibleRandom should return different values")
+}
+
+access(all)
+fun getEVMRevertibleRandom(coaHost: Address, testAddress: EVM.EVMAddress): UInt64 {
+ return 0
+}
\ No newline at end of file
diff --git a/cadence/tests/scripts/evm_revertible_random.cdc b/cadence/tests/scripts/evm_revertible_random.cdc
new file mode 100644
index 0000000..2f0beab
--- /dev/null
+++ b/cadence/tests/scripts/evm_revertible_random.cdc
@@ -0,0 +1,16 @@
+import "EVM"
+
+access(all)
+fun main(coaHost: Address, testAddress: EVM.EVMAddress): UInt64 {
+ let coa = getAuthAccount(coaHost).storage
+ .borrow(from: /storage/evm)!
+ let res = coa.call(
+ to: testAddress,
+ data: EVM.encodeABIWithSignature("getRevertibleRandomInRange(uint64,uint64)", [UInt64(0), UInt64(1000)]),
+ gasLimit: 15_000_000,
+ value: EVM.Balance(attoflow: 0)
+ )
+ assert(res.status == EVM.Status.successful, message: "getRevertibleRandomInRange failed")
+ let decoded = EVM.decodeABI(types: [Type()], data: res.data)
+ return decoded[0] as! UInt64
+}
diff --git a/cadence/tests/test_helpers.cdc b/cadence/tests/test_helpers.cdc
new file mode 100644
index 0000000..8fe156d
--- /dev/null
+++ b/cadence/tests/test_helpers.cdc
@@ -0,0 +1,44 @@
+import Test
+
+// Bytecode constants
+access(all) let wflowBytecode = "6080604052600436106100ae5763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166306fdde0381146100b8578063095ea7b31461014257806318160ddd1461017a57806323b872dd146101a15780632e1a7d4d146101cb578063313ce567146101e357806370a082311461020e57806395d89b411461022f578063a9059cbb14610244578063d0e30db0146100ae578063dd62ed3e14610268575b6100b661028f565b005b3480156100c457600080fd5b506100cd6102e7565b6040805160208082528351818301528351919283929083019185019080838360005b838110156101075781810151838201526020016100ef565b50505050905090810190601f1680156101345780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561014e57600080fd5b50610166600160a060020a0360043516602435610375565b604080519115158252519081900360200190f35b34801561018657600080fd5b5061018f6103df565b60408051918252519081900360200190f35b3480156101ad57600080fd5b50610166600160a060020a03600435811690602435166044356103ed565b3480156101d757600080fd5b506100b6600435610533565b3480156101ef57600080fd5b506101f86105e3565b6040805160ff9092168252519081900360200190f35b34801561021a57600080fd5b5061018f600160a060020a03600435166105ec565b34801561023b57600080fd5b506100cd6105fe565b34801561025057600080fd5b50610166600160a060020a0360043516602435610658565b34801561027457600080fd5b5061018f600160a060020a036004358116906024351661066c565b600160a060020a033316600081815260036020908152604091829020805434908101909155825190815291517fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c9281900390910190a2565b6000805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152929183018282801561036d5780601f106103425761010080835404028352916020019161036d565b820191906000526020600020905b81548152906001019060200180831161035057829003601f168201915b505050505081565b600160a060020a03338116600081815260046020908152604080832094871680845294825280832086905580518681529051929493927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925929181900390910190a350600192915050565b600160a060020a0330163190565b600160a060020a03831660009081526003602052604081205482111561041257600080fd5b33600160a060020a031684600160a060020a03161415801561045c5750600160a060020a038085166000908152600460209081526040808320339094168352929052205460001914155b156104c257600160a060020a038085166000908152600460209081526040808320339094168352929052205482111561049457600080fd5b600160a060020a03808516600090815260046020908152604080832033909416835292905220805483900390555b600160a060020a03808516600081815260036020908152604080832080548890039055938716808352918490208054870190558351868152935191937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929081900390910190a35060019392505050565b600160a060020a03331660009081526003602052604090205481111561055857600080fd5b600160a060020a033316600081815260036020526040808220805485900390555183156108fc0291849190818181858888f193505050501580156105a0573d6000803e3d6000fd5b50604080518281529051600160a060020a033316917f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65919081900360200190a250565b60025460ff1681565b60036020526000908152604090205481565b60018054604080516020600284861615610100026000190190941693909304601f8101849004840282018401909252818152929183018282801561036d5780601f106103425761010080835404028352916020019161036d565b60006106653384846103ed565b9392505050565b6004602090815260009283526040808420909152908252902054815600a165627a7a72305820e1e0e82b179f331bf99f3294d4266cb1da578c59c07c2de6693f8cb10226617a0029"
+access(all) let erc721Bytecode = "60806040523480156200001157600080fd5b506040516200181b3803806200181b833981016040819052620000349162000208565b338585600062000045838262000332565b50600162000054828262000332565b5050506001600160a01b0381166200008657604051631e4fbdf760e01b81526000600482015260240160405180910390fd5b6200009181620000d1565b50600780546001600160a01b039485166001600160a01b0319918216179091556008929092556009805491909316911617905550506000600a55620003fe565b600680546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200014b57600080fd5b81516001600160401b038082111562000168576200016862000123565b604051601f8301601f19908116603f0116810190828211818310171562000193576200019362000123565b8160405283815260209250866020858801011115620001b157600080fd5b600091505b83821015620001d55785820183015181830184015290820190620001b6565b6000602085830101528094505050505092915050565b80516001600160a01b03811681146200020357600080fd5b919050565b600080600080600060a086880312156200022157600080fd5b85516001600160401b03808211156200023957600080fd5b6200024789838a0162000139565b965060208801519150808211156200025e57600080fd5b506200026d8882890162000139565b9450506200027e60408701620001eb565b9250606086015191506200029560808701620001eb565b90509295509295909350565b600181811c90821680620002b657607f821691505b602082108103620002d757634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200032d576000816000526020600020601f850160051c81016020861015620003085750805b601f850160051c820191505b81811015620003295782815560010162000314565b5050505b505050565b81516001600160401b038111156200034e576200034e62000123565b62000366816200035f8454620002a1565b84620002dd565b602080601f8311600181146200039e5760008415620003855750858301515b600019600386901b1c1916600185901b17855562000329565b600085815260208120601f198616915b82811015620003cf57888601518255948401946001909101908401620003ae565b5085821015620003ee5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b61140d806200040e6000396000f3fe608060405234801561001057600080fd5b50600436106101375760003560e01c806370a08231116100b8578063a22cb4651161007c578063a22cb4651461026b578063b88d4fde1461027e578063bdb4b84814610291578063c87b56dd1461029a578063e985e9c5146102ad578063f2fde38b146102c057600080fd5b806370a0823114610224578063715018a6146102375780638bca6d161461023f5780638da5cb5b1461025257806395d89b411461026357600080fd5b806318160ddd116100ff57806318160ddd146101c157806323b872dd146101d857806338af3eed146101eb57806342842e0e146101fe5780636352211e1461021157600080fd5b806301ffc9a71461013c57806306fdde0314610164578063081812fc14610179578063095ea7b3146101a45780631249c58b146101b9575b600080fd5b61014f61014a366004610fb5565b6102d3565b60405190151581526020015b60405180910390f35b61016c610325565b60405161015b9190611022565b61018c610187366004611035565b6103b7565b6040516001600160a01b03909116815260200161015b565b6101b76101b236600461106a565b6103e0565b005b6101b76103ef565b6101ca600a5481565b60405190815260200161015b565b6101b76101e6366004611094565b6103f9565b60095461018c906001600160a01b031681565b6101b761020c366004611094565b610489565b61018c61021f366004611035565b6104a9565b6101ca6102323660046110d0565b6104b4565b6101b76104fc565b60075461018c906001600160a01b031681565b6006546001600160a01b031661018c565b61016c61050e565b6101b76102793660046110f9565b61051d565b6101b761028c366004611146565b610528565b6101ca60085481565b61016c6102a8366004611035565b610540565b61014f6102bb366004611222565b6105b5565b6101b76102ce3660046110d0565b6105e3565b60006001600160e01b031982166380ac58cd60e01b148061030457506001600160e01b03198216635b5e139f60e01b145b8061031f57506301ffc9a760e01b6001600160e01b03198316145b92915050565b60606000805461033490611255565b80601f016020809104026020016040519081016040528092919081815260200182805461036090611255565b80156103ad5780601f10610382576101008083540402835291602001916103ad565b820191906000526020600020905b81548152906001019060200180831161039057829003601f168201915b5050505050905090565b60006103c282610621565b506000828152600460205260409020546001600160a01b031661031f565b6103eb82823361065a565b5050565b6103f7610667565b565b6001600160a01b03821661042857604051633250574960e11b8152600060048201526024015b60405180910390fd5b6000610435838333610746565b9050836001600160a01b0316816001600160a01b031614610483576040516364283d7b60e01b81526001600160a01b038086166004830152602482018490528216604482015260640161041f565b50505050565b6104a483838360405180602001604052806000815250610528565b505050565b600061031f82610621565b60006001600160a01b0382166104e0576040516322718ad960e21b81526000600482015260240161041f565b506001600160a01b031660009081526003602052604090205490565b61050461083f565b6103f7600061086c565b60606001805461033490611255565b6103eb3383836108be565b6105338484846103f9565b610483338585858561095d565b606061054b82610621565b50600061056360408051602081019091526000815290565b9050600081511161058357604051806020016040528060008152506105ae565b8061058d84610a88565b60405160200161059e92919061128f565b6040516020818303038152906040525b9392505050565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b6105eb61083f565b6001600160a01b03811661061557604051631e4fbdf760e01b81526000600482015260240161041f565b61061e8161086c565b50565b6000818152600260205260408120546001600160a01b03168061031f57604051637e27328960e01b81526004810184905260240161041f565b6104a48383836001610b1b565b61066f610c21565b6007546009546008546040516323b872dd60e01b81523360048201526001600160a01b03928316602482015260448101919091529116906323b872dd906064016020604051808303816000875af19250505080156106ea575060408051601f3d908101601f191682019092526106e7918101906112be565b60015b6107245760075460085460405163760a9bc360e11b81526001600160a01b039092166004830152336024830152604482015260640161041f565b50600a8054906000610735836112db565b91905055506103f733600a54610c62565b6000828152600260205260408120546001600160a01b039081169083161561077357610773818486610cc7565b6001600160a01b038116156107b157610790600085600080610b1b565b6001600160a01b038116600090815260036020526040902080546000190190555b6001600160a01b038516156107e0576001600160a01b0385166000908152600360205260409020805460010190555b60008481526002602052604080822080546001600160a01b0319166001600160a01b0389811691821790925591518793918516917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4949350505050565b6006546001600160a01b031633146103f75760405163118cdaa760e01b815233600482015260240161041f565b600680546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6001600160a01b0382166108f057604051630b61174360e31b81526001600160a01b038316600482015260240161041f565b6001600160a01b03838116600081815260056020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b6001600160a01b0383163b15610a8157604051630a85bd0160e11b81526001600160a01b0384169063150b7a029061099f908890889087908790600401611302565b6020604051808303816000875af19250505080156109da575060408051601f3d908101601f191682019092526109d79181019061133f565b60015b610a43573d808015610a08576040519150601f19603f3d011682016040523d82523d6000602084013e610a0d565b606091505b508051600003610a3b57604051633250574960e11b81526001600160a01b038516600482015260240161041f565b805181602001fd5b6001600160e01b03198116630a85bd0160e11b14610a7f57604051633250574960e11b81526001600160a01b038516600482015260240161041f565b505b5050505050565b60606000610a9583610d2b565b600101905060008167ffffffffffffffff811115610ab557610ab5611130565b6040519080825280601f01601f191660200182016040528015610adf576020820181803683370190505b5090508181016020015b600019016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a8504945084610ae957509392505050565b8080610b2f57506001600160a01b03821615155b15610bf1576000610b3f84610621565b90506001600160a01b03831615801590610b6b5750826001600160a01b0316816001600160a01b031614155b8015610b7e5750610b7c81846105b5565b155b15610ba75760405163a9fbf51f60e01b81526001600160a01b038416600482015260240161041f565b8115610bef5783856001600160a01b0316826001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45b505b5050600090815260046020526040902080546001600160a01b0319166001600160a01b0392909216919091179055565b6000610c2b610e03565b9050610c3860028261135c565b67ffffffffffffffff1660010361061e576040516351d099d960e11b815260040160405180910390fd5b6001600160a01b038216610c8c57604051633250574960e11b81526000600482015260240161041f565b6000610c9a83836000610746565b90506001600160a01b038116156104a4576040516339e3563760e11b81526000600482015260240161041f565b610cd2838383610f3c565b6104a4576001600160a01b038316610d0057604051637e27328960e01b81526004810182905260240161041f565b60405163177e802f60e01b81526001600160a01b03831660048201526024810182905260440161041f565b60008072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b8310610d6a5772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6d04ee2d6d415b85acef81000000008310610d96576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc100008310610db457662386f26fc10000830492506010015b6305f5e1008310610dcc576305f5e100830492506008015b6127108310610de057612710830492506004015b60648310610df2576064830492506002015b600a831061031f5760010192915050565b60408051600481526024810182526020810180516001600160e01b0316630382fd5960e51b1790529051600091829182916801000000000000000191610e499190611391565b600060405180830381855afa9150503d8060008114610e84576040519150601f19603f3d011682016040523d82523d6000602084013e610e89565b606091505b509150915081610f1e5760405162461bcd60e51b815260206004820152605460248201527f556e7375636365737366756c2063616c6c20746f20436164656e63652041726360448201527f68207072652d636f6d70696c65207768656e206665746368696e672072657665606482015273393a34b13632903930b73237b690373ab6b132b960611b608482015260a40161041f565b600081806020019051810190610f3491906113ad565b949350505050565b60006001600160a01b03831615801590610f345750826001600160a01b0316846001600160a01b03161480610f765750610f7684846105b5565b80610f345750506000908152600460205260409020546001600160a01b03908116911614919050565b6001600160e01b03198116811461061e57600080fd5b600060208284031215610fc757600080fd5b81356105ae81610f9f565b60005b83811015610fed578181015183820152602001610fd5565b50506000910152565b6000815180845261100e816020860160208601610fd2565b601f01601f19169290920160200192915050565b6020815260006105ae6020830184610ff6565b60006020828403121561104757600080fd5b5035919050565b80356001600160a01b038116811461106557600080fd5b919050565b6000806040838503121561107d57600080fd5b6110868361104e565b946020939093013593505050565b6000806000606084860312156110a957600080fd5b6110b28461104e565b92506110c06020850161104e565b9150604084013590509250925092565b6000602082840312156110e257600080fd5b6105ae8261104e565b801515811461061e57600080fd5b6000806040838503121561110c57600080fd5b6111158361104e565b91506020830135611125816110eb565b809150509250929050565b634e487b7160e01b600052604160045260246000fd5b6000806000806080858703121561115c57600080fd5b6111658561104e565b93506111736020860161104e565b925060408501359150606085013567ffffffffffffffff8082111561119757600080fd5b818701915087601f8301126111ab57600080fd5b8135818111156111bd576111bd611130565b604051601f8201601f19908116603f011681019083821181831017156111e5576111e5611130565b816040528281528a60208487010111156111fe57600080fd5b82602086016020830137600060208483010152809550505050505092959194509250565b6000806040838503121561123557600080fd5b61123e8361104e565b915061124c6020840161104e565b90509250929050565b600181811c9082168061126957607f821691505b60208210810361128957634e487b7160e01b600052602260045260246000fd5b50919050565b600083516112a1818460208801610fd2565b8351908301906112b5818360208801610fd2565b01949350505050565b6000602082840312156112d057600080fd5b81516105ae816110eb565b6000600182016112fb57634e487b7160e01b600052601160045260246000fd5b5060010190565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061133590830184610ff6565b9695505050505050565b60006020828403121561135157600080fd5b81516105ae81610f9f565b600067ffffffffffffffff8084168061138557634e487b7160e01b600052601260045260246000fd5b92169190910692915050565b600082516113a3818460208701610fd2565b9190910192915050565b6000602082840312156113bf57600080fd5b815167ffffffffffffffff811681146105ae57600080fdfea26469706673582212204919ee1872648a1b85d633af14a8f8c7163d176b6699f75fe4e22d677fc562ae64736f6c63430008180033"
+access(all) let testBytecode = "608060405234801561001057600080fd5b50611210806100206000396000f3fe608060405234801561001057600080fd5b50600436106100575760003560e01c80635461f2e41461005c578063bc26d8241461008c578063d59fd63c1461009f578063f8413b07146100c2578063fc177f7f146100d8575b600080fd5b61006f61006a366004610fac565b6100eb565b6040516001600160401b0390911681526020015b60405180910390f35b61006f61009a366004610fe5565b610100565b6100b26100ad366004610fe5565b61010b565b6040519015158152602001610083565b6100ca610189565b604051908152602001610083565b61006f6100e6366004610ffe565b610198565b60006100f783836101ad565b90505b92915050565b60006100fa82610225565b600080610119600184611056565b600054909150811061012e5750600092915050565b600080828154811061014257610142611069565b90600052602060002090600302019050600061015c6102df565b600283015490915060ff16158015610180575081546001600160401b038083169116105b95945050505050565b600061019361040e565b905090565b60006101a584848461054f565b949350505050565b6000806101b861060d565b6040516020016101ca91815260200190565b60408051601f1981840301815282825243602084015292506000910160408051601f1981840301815282820190915260008083526020830152915061021081848461066a565b61021b81878761079d565b9695505050505050565b600080610231836108cc565b60405160200161024391815260200190565b60408051601f198184030181528282526020830186905292506000910160408051601f1981840301815282820190915260008083526020830152915061028a81848461066a565b600061029582610a11565b6040516001600160401b038216815290915086907fe3e452ff947e18cea0f62f23d405e522ac808f69346c5f59ddc4bd722ac10d039060200160405180910390a295945050505050565b60408051600481526024810182526020810180516001600160e01b03166329f43eb360e11b179052905160009182918291680100000000000000019161032591906110af565b600060405180830381855afa9150503d8060008114610360576040519150601f19603f3d011682016040523d82523d6000602084013e610365565b606091505b5091509150816103f85760405162461bcd60e51b815260206004820152604d60248201527f556e7375636365737366756c2063616c6c20746f20436164656e63652041726360448201527f68207072652d636f6d70696c65207768656e206665746368696e6720466c6f7760648201526c08189b1bd8dac81a195a59da1d609a1b608482015260a4015b60405180910390fd5b6000818060200190518101906101a591906110bb565b600180546000918261041f836110df565b919050555060006001549050600060405180606001604052806104406102df565b6001600160401b0390811682524360208084019190915260006040938401819052805460018101825590805284517f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5636003909202918201805467ffffffffffffffff191691909416908117909355848201517f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5648201819055858501517f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e565909201805460ff19169215159290921790915583519283529082015291925083917f7886956edccde10901843c3e51fc26016455e9248e210a29c2a57ead63ad226e910160405180910390a250919050565b60008061055b856108cc565b60405160200161056d91815260200190565b60408051601f198184030181528282526020830188905292506000910160408051601f198184030181528282019091526000808352602083015291506105b481848461066a565b60006105c182888861079d565b6040516001600160401b038216815290915088907fe3e452ff947e18cea0f62f23d405e522ac808f69346c5f59ddc4bd722ac10d039060200160405180910390a2979650505050505050565b600080610618610a6e565b6001600160401b03169050604061062d610a6e565b6001600160401b0316901b176080610643610a6e565b6001600160401b0316901b1760c0610659610a6e565b6001600160401b0316901b17919050565b6010825110156106f05760405162461bcd60e51b815260206004820152604560248201527f4174206c65617374203136206279746573206f6620656e74726f70792073686f60448201527f756c642062652075736564207768656e20696e697469616c697a696e67207468606482015264652050524760d81b608482015260a4016103ef565b600082826040516020016107059291906110f8565b604051602081830303815290604052905060008180519060200120905061074e8160405160200161073891815260200190565b6040516020818303038152906040526000610b89565b6001600160401b03168552604080516020810183905261077f91016040516020818303038152906040526008610b89565b6001600160401b0316602086015261079685610c41565b5050505050565b6000826001600160401b0316826001600160401b0316116108005760405162461bcd60e51b815260206004820152601c60248201527f4d6178206d7573742062652067726561746572207468616e206d696e0000000060448201526064016103ef565b600061080c848461110d565b9050600061081982610cda565b9050600061083460016001600160401b03841681901b611056565b9050600061084483610100611134565b6001600160401b03169050600080600061085d8b610d10565b90505b8481169150866001600160401b0316826001600160401b031611156108b3576001600160401b0386161c82610894816110df565b9350508383036108ae576108a78b610d10565b9050600092505b610860565b6108bd828b611168565b9b9a5050505050505050505050565b6000806108da600184611056565b600054909150811061095f5760405162461bcd60e51b815260206004820152604260248201527f496e76616c69642072657175657374204944202d2076616c756520657863656560448201527f647320746865206e756d626572206f66206578697374696e6720726571756573606482015261747360f01b608482015260a4016103ef565b600080828154811061097357610973611069565b9060005260206000209060030201905061098c81610d72565b60028101805460ff1916600117905580546000906109b2906001600160401b0316610e5b565b82546001840154604080516001600160401b0390931683526020830191909152810182905290915085907f01f207584638dfbb3f1d85bba3809672fcb07a3d2e291308293ba78b7f1984909060600160405180910390a2949350505050565b6000610a1c82610c41565b5080516020820180516001600160401b03808216909452601783901b6a7fffffffffffffff80000016909218601181901c657fffffffffff1618601a83901c643fffffffff1683181892831690520190565b60408051600481526024810182526020810180516001600160e01b0316630382fd5960e51b1790529051600091829182916801000000000000000191610ab491906110af565b600060405180830381855afa9150503d8060008114610aef576040519150601f19603f3d011682016040523d82523d6000602084013e610af4565b606091505b5091509150816103f85760405162461bcd60e51b815260206004820152605460248201527f556e7375636365737366756c2063616c6c20746f20436164656e63652041726360448201527f68207072652d636f6d70696c65207768656e206665746368696e672072657665606482015273393a34b13632903930b73237b690373ab6b132b960611b608482015260a4016103ef565b6000610b96826008611188565b83511015610bdc5760405162461bcd60e51b8152602060048201526013602482015272092dcecc2d8d2c840c4f2e8ca40d8cadccee8d606b1b60448201526064016103ef565b6000805b6008811015610c395784610bf48286611188565b81518110610c0457610c04611069565b602001015160f81c60f81b60f81c60ff166008836001600160401b0316901b1791508080610c31906110df565b915050610be0565b509392505050565b80516001600160401b0316151580610c65575060208101516001600160401b031615155b610cd75760405162461bcd60e51b815260206004820152603860248201527f50524720696e697469616c2073746174652069732030202d206d75737420626560448201527f20696e697469616c697a6564206173206e6f6e2d7a65726f000000000000000060648201526084016103ef565b50565b6000805b6001600160401b038316156100fa576001836001600160401b0316901c92508080610d089061119b565b915050610cde565b600080610d1c83610a11565b6001600160401b031690506040610d3284610a11565b6001600160401b0316901b176080610d4984610a11565b6001600160401b0316901b1760c0610d6084610a11565b6001600160401b0316901b1792915050565b600281015460ff1615610dc75760405162461bcd60e51b815260206004820152601960248201527f5265717565737420616c72656164792066756c66696c6c65640000000000000060448201526064016103ef565b610dcf6102df565b81546001600160401b03918216911610610cd75760405162461bcd60e51b815260206004820152604160248201527f43616e6e6f742066756c66696c6c207265717565737420756e74696c2073756260448201527f73657175656e7420466c6f77206e6574776f726b20626c6f636b2068656967686064820152601d60fa1b608482015260a4016103ef565b6040516001600160401b038216602482015260009081908190680100000000000000019060440160408051601f198184030181529181526020820180516001600160e01b0316633c53afdf60e11b17905251610eb791906110af565b600060405180830381855afa9150503d8060008114610ef2576040519150601f19603f3d011682016040523d82523d6000602084013e610ef7565b606091505b509150915081610f815760405162461bcd60e51b815260206004820152604960248201527f556e7375636365737366756c2063616c6c20746f20436164656e63652041726360448201527f68207072652d636f6d70696c65207768656e206665746368696e672072616e646064820152686f6d20736f7572636560b81b608482015260a4016103ef565b60008180602001905181019061018091906111c1565b6001600160401b0381168114610cd757600080fd5b60008060408385031215610fbf57600080fd5b8235610fca81610f97565b91506020830135610fda81610f97565b809150509250929050565b600060208284031215610ff757600080fd5b5035919050565b60008060006060848603121561101357600080fd5b83359250602084013561102581610f97565b9150604084013561103581610f97565b809150509250925092565b634e487b7160e01b600052601160045260246000fd5b818103818111156100fa576100fa611040565b634e487b7160e01b600052603260045260246000fd5b6000815160005b818110156110a05760208185018101518683015201611086565b50600093019283525090919050565b60006100f7828461107f565b6000602082840312156110cd57600080fd5b81516110d881610f97565b9392505050565b6000600182016110f1576110f1611040565b5060010190565b60006101a5611107838661107f565b8461107f565b6001600160401b0382811682821603908082111561112d5761112d611040565b5092915050565b60006001600160401b038084168061115c57634e487b7160e01b600052601260045260246000fd5b92169190910492915050565b6001600160401b0381811683821601908082111561112d5761112d611040565b808201808211156100fa576100fa611040565b60006001600160401b038083168181036111b7576111b7611040565b6001019392505050565b6000602082840312156111d357600080fd5b505191905056fea2646970667358221220f8c9a068ce5c9c1b3f61e3676f66b60a38347f8e7f4830594074a9377b82688564736f6c63430008130033"
+
+/* --- Getters --- */
+
+access(all)
+fun getWFLOWBytecode(): String {
+ return wflowBytecode
+}
+
+access(all)
+fun getERC721Bytecode(): String {
+ return erc721Bytecode
+}
+
+access(all)
+fun getTestBytecode(): String {
+ return testBytecode
+}
+
+access(all)
+fun moveBlock() {
+ let res = _executeTransaction(
+ "./transactions/move_block.cdc",
+ [],
+ Test.serviceAccount()
+ )
+ Test.expect(res, Test.beSucceeded())
+}
+
+access(all)
+fun _executeTransaction(_ path: String, _ args: [AnyStruct], _ signer: Test.TestAccount): Test.TransactionResult {
+ let txn = Test.Transaction(
+ code: Test.readFile(path),
+ authorizers: [signer.address],
+ signers: [signer],
+ arguments: args
+ )
+ return Test.executeTransaction(txn)
+}
\ No newline at end of file
diff --git a/cadence/tests/transactions/create_coa.cdc b/cadence/tests/transactions/create_coa.cdc
new file mode 100644
index 0000000..d60ca38
--- /dev/null
+++ b/cadence/tests/transactions/create_coa.cdc
@@ -0,0 +1,51 @@
+import "EVM"
+import "FungibleToken"
+import "FlowToken"
+
+/// Configures a COA in the signer's Flow account, funding with the specified amount. If the COA already exists, the
+/// transaction reverts.
+///
+transaction(amount: UFix64) {
+ let coa: &EVM.CadenceOwnedAccount
+ let sentVault: @FlowToken.Vault
+
+ prepare(signer: auth(BorrowValue, IssueStorageCapabilityController, PublishCapability, SaveValue, UnpublishCapability) &Account) {
+ let storagePath = /storage/evm
+ let publicPath = /public/evm
+
+ // Revert if the CadenceOwnedAccount already exists
+ if signer.storage.type(at: storagePath) != nil {
+ panic("Storage collision - Resource already stored at path=".concat(storagePath.toString()))
+ }
+
+ // Configure the CadenceOwnedAccount
+ signer.storage.save<@EVM.CadenceOwnedAccount>(<-EVM.createCadenceOwnedAccount(), to: storagePath)
+ let addressableCap = signer.capabilities.storage.issue<&EVM.CadenceOwnedAccount>(storagePath)
+ signer.capabilities.unpublish(publicPath)
+ signer.capabilities.publish(addressableCap, at: publicPath)
+
+ // Reference the CadeceOwnedAccount
+ self.coa = signer.storage.borrow(from: /storage/evm)
+ ?? panic("Missing or mis-typed CadenceOwnedAccount at /storage/evm")
+
+ // Withdraw the amount from the signer's FlowToken vault
+ let vaultRef = signer.storage.borrow(
+ from: /storage/flowTokenVault
+ ) ?? panic("Could not borrow reference to the owner's Vault!")
+ self.sentVault <- vaultRef.withdraw(amount: amount) as! @FlowToken.Vault
+ }
+
+ pre {
+ self.sentVault.balance == amount:
+ "Expected amount =".concat(amount.toString()).concat(" but sentVault.balance=").concat(self.sentVault.balance.toString())
+ }
+
+ execute {
+ // Deposit the amount into the CadenceOwnedAccount if the balance is greater than zero
+ if self.sentVault.balance > 0.0 {
+ self.coa.deposit(from: <-self.sentVault)
+ } else {
+ destroy self.sentVault
+ }
+ }
+}
\ No newline at end of file
diff --git a/cadence/tests/transactions/deploy.cdc b/cadence/tests/transactions/deploy.cdc
new file mode 100644
index 0000000..221fef8
--- /dev/null
+++ b/cadence/tests/transactions/deploy.cdc
@@ -0,0 +1,56 @@
+import "FungibleToken"
+import "FlowToken"
+
+import "EVM"
+
+/// Deploys a compiled solidity contract from bytecode to the EVM, with the signer's COA as the deployer
+///
+transaction(bytecode: String, gasLimit: UInt64, value: UFix64) {
+
+ let coa: auth(EVM.Deploy) &EVM.CadenceOwnedAccount
+ var sentVault: @FlowToken.Vault?
+
+ prepare(signer: auth(BorrowValue) &Account) {
+
+ let storagePath = StoragePath(identifier: "evm")!
+ self.coa = signer.storage.borrow(from: storagePath)
+ ?? panic("Could not borrow reference to the signer's bridged account")
+
+ // Rebalance Flow across VMs if there is not enough Flow in the EVM account to cover the value
+ let evmFlowBalance: UFix64 = self.coa.balance().inFLOW()
+ if self.coa.balance().inFLOW() < value {
+ let withdrawAmount: UFix64 = value - evmFlowBalance
+ let vaultRef = signer.storage.borrow(
+ from: /storage/flowTokenVault
+ ) ?? panic("Could not borrow reference to the owner's Vault!")
+
+ self.sentVault <- vaultRef.withdraw(amount: withdrawAmount) as! @FlowToken.Vault
+ } else {
+ self.sentVault <- nil
+ }
+ }
+
+ execute {
+
+ // Deposit Flow into the EVM account if necessary otherwise destroy the sent Vault
+ if self.sentVault != nil {
+ self.coa.deposit(from: <-self.sentVault!)
+ } else {
+ destroy self.sentVault
+ }
+
+ let valueBalance = EVM.Balance(attoflow: 0)
+ valueBalance.setFLOW(flow: value)
+ // Finally deploy the contract
+ let evmResult = self.coa.deploy(
+ code: bytecode.decodeHex(),
+ gasLimit: gasLimit,
+ value: valueBalance
+ )
+ assert(
+ evmResult.status == EVM.Status.successful && evmResult.deployedContract != nil,
+ message: "EVM deployment failed with error code: ".concat(evmResult.errorCode.toString())
+ .concat(" and message: ").concat(evmResult.errorMessage)
+ )
+ }
+}
diff --git a/cadence/tests/transactions/move_block.cdc b/cadence/tests/transactions/move_block.cdc
new file mode 100644
index 0000000..aa50595
--- /dev/null
+++ b/cadence/tests/transactions/move_block.cdc
@@ -0,0 +1,19 @@
+import "EVM"
+
+transaction {
+ let coa: auth(EVM.Call) &EVM.CadenceOwnedAccount
+ prepare(signer: auth(BorrowValue) &Account) {
+ self.coa = signer.storage.borrow(from: /storage/evm)
+ ?? panic("A CadenceOwnedAccount (COA) Resource could not be found at path /storage/evm")
+ }
+
+ execute {
+ let res = self.coa.call(
+ to: self.coa.address(),
+ data: [],
+ gasLimit: 15_000_000,
+ value: EVM.Balance(attoflow: 0)
+ )
+ assert(res.status == EVM.Status.successful, message: "Empty EVM call failed")
+ }
+}
diff --git a/cadence/tests/wrap_and_mint_tests.cdc b/cadence/tests/wrap_and_mint_tests.cdc
new file mode 100644
index 0000000..fde9ff2
--- /dev/null
+++ b/cadence/tests/wrap_and_mint_tests.cdc
@@ -0,0 +1,99 @@
+import Test
+import BlockchainHelpers
+import "test_helpers.cdc"
+
+import "EVM"
+
+access(all) let serviceAccount = Test.serviceAccount()
+
+access(all) var coaAddress: String = ""
+access(all) var wflowAddress: String = ""
+access(all) var erc721Address: String = ""
+
+access(all)
+fun setup() {
+ // Create & fund a CadenceOwnedAccount
+ let coaRes = executeTransaction(
+ "./transactions/create_coa.cdc",
+ [100.0],
+ serviceAccount
+ )
+ Test.expect(coaRes, Test.beSucceeded())
+
+ // Extract COA address from event
+ let coaEvts = Test.eventsOfType(Type())
+ let coaEvt = coaEvts[0] as! EVM.CadenceOwnedAccountCreated
+ coaAddress = coaEvt.address
+ log("COA address: ".concat(coaAddress))
+
+ // Deploy WFLOW
+ let wflowDeployRes = executeTransaction(
+ "./transactions/deploy.cdc",
+ [getWFLOWBytecode(), UInt64(15_000_000), 0.0],
+ serviceAccount
+ )
+ Test.expect(wflowDeployRes, Test.beSucceeded())
+
+ // Extract WFLOW address from event
+ var txnExecEvts = Test.eventsOfType(Type())
+ let wflowEvt = txnExecEvts[2] as! EVM.TransactionExecuted
+ wflowAddress = wflowEvt.contractAddress
+
+ // Deploy ERC721
+ let constructorArgs = [
+ "Maybe Mint ERC721",
+ "MAYBE",
+ EVM.addressFromString(wflowAddress),
+ UInt256(1_000_000_000_000_000_000),
+ EVM.addressFromString(coaAddress)
+ ]
+ // Encode constructor args as ABI and then as hex
+ let argsBytecode = String.encodeHex(EVM.encodeABI(
+ constructorArgs
+ ))
+ // Append the encoded constructor args to the compiled bytecode
+ let finalBytecode = getERC721Bytecode().concat(argsBytecode)
+ let erc721DeployRes = executeTransaction(
+ "./transactions/deploy.cdc",
+ [finalBytecode, UInt64(15_000_000), 0.0],
+ serviceAccount
+ )
+ Test.expect(erc721DeployRes, Test.beSucceeded())
+
+ // Extract ERC721 address from event
+ txnExecEvts = Test.eventsOfType(Type())
+ let erc721Evt = txnExecEvts[3] as! EVM.TransactionExecuted
+ erc721Address = erc721Evt.contractAddress
+
+ log("WFLOW address: ".concat(wflowAddress))
+ log("ERC721 address: ".concat(erc721Address))
+}
+
+access(all)
+fun testWrapAndMintSucceeds() {
+ let user = Test.createAccount()
+ mintFlow(to: user, amount: 10.0)
+
+ wrapAndMintUntilSuccess(signer: user, wflow: wflowAddress, erc721: erc721Address)
+}
+
+access(all)
+fun wrapAndMintUntilSuccess(signer: Test.TestAccount, wflow: String, erc721: String) {
+ var i = 0
+ var success = false
+ while i < 50 {
+ let res: Test.TransactionResult = executeTransaction(
+ "../transactions/bundled/wrap_and_mint.cdc",
+ [wflow, erc721],
+ signer
+ )
+ if res.error == nil {
+ success = true
+ break
+ } else {
+ i = i + 1
+ moveBlock()
+ }
+ }
+ Test.assertEqual(true, success)
+}
\ No newline at end of file
diff --git a/solidity/src/test/TestCadenceRandomConsumer.sol b/solidity/src/test/TestCadenceRandomConsumer.sol
new file mode 100644
index 0000000..950b6f2
--- /dev/null
+++ b/solidity/src/test/TestCadenceRandomConsumer.sol
@@ -0,0 +1,29 @@
+// SPDX-License-Identifier: Unlicense
+pragma solidity 0.8.19;
+
+import {CadenceRandomConsumer} from "onflow/random-coin-toss/solidity/src/CadenceRandomConsumer.sol";
+
+/**
+ * @dev This contract extends CadenceRandomConsumer to expose internal functions for testing.
+ */
+contract TestCadenceRandomConsumer is CadenceRandomConsumer {
+ // Expose internal _getRevertibleRandomInRange function for testing
+ function getRevertibleRandomInRange(uint64 min, uint64 max) public view returns (uint64) {
+ return _getRevertibleRandomInRange(min, max);
+ }
+
+ // Expose internal _requestRandomness function for testing
+ function requestRandomness() public returns (uint256) {
+ return _requestRandomness();
+ }
+
+ // Expose internal _fulfillRandomRequest function for testing
+ function fulfillRandomRequest(uint256 requestId) public returns (uint64) {
+ return _fulfillRandomRequest(requestId);
+ }
+
+ // Expose internal _fulfillRandomInRange function for testing
+ function fulfillRandomInRange(uint256 requestId, uint64 min, uint64 max) public returns (uint64) {
+ return _fulfillRandomInRange(requestId, min, max);
+ }
+}
From bffd6322e89c83ee8db4163cbced09cf23adb12b Mon Sep 17 00:00:00 2001
From: Giovanni Sanchez <108043524+sisyphusSmiling@users.noreply.github.com>
Date: Thu, 7 Nov 2024 14:02:46 -0700
Subject: [PATCH 18/20] forge install: flow-sol-utils
---
.gitmodules | 3 +++
solidity/lib/flow-sol-utils | 1 +
2 files changed, 4 insertions(+)
create mode 160000 solidity/lib/flow-sol-utils
diff --git a/.gitmodules b/.gitmodules
index 0254bef..35f6bab 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -7,3 +7,6 @@
[submodule "solidity/lib/forge-std"]
path = solidity/lib/forge-std
url = https://github.com/foundry-rs/forge-std
+[submodule "solidity/lib/flow-sol-utils"]
+ path = solidity/lib/flow-sol-utils
+ url = https://github.com/onflow/flow-sol-utils
diff --git a/solidity/lib/flow-sol-utils b/solidity/lib/flow-sol-utils
new file mode 160000
index 0000000..082dd3e
--- /dev/null
+++ b/solidity/lib/flow-sol-utils
@@ -0,0 +1 @@
+Subproject commit 082dd3ec59eea0e8afacb3b49903a7564ce9ce66
From c4b6971f57defb480cc51ba1915e0a0df10f3340 Mon Sep 17 00:00:00 2001
From: Giovanni Sanchez <108043524+sisyphusSmiling@users.noreply.github.com>
Date: Thu, 7 Nov 2024 14:11:17 -0700
Subject: [PATCH 19/20] update solidity dependencies to use flow-sol-utils
---
remappings.txt | 2 +-
solidity/src/MaybeMintERC721.sol | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/remappings.txt b/remappings.txt
index 5776ef6..037966e 100644
--- a/remappings.txt
+++ b/remappings.txt
@@ -3,4 +3,4 @@ ds-test/=solidity/lib/forge-std/lib/ds-test/src/
erc4626-tests/=solidity/lib/openzeppelin-contracts/lib/erc4626-tests/
forge-std/=solidity/lib/forge-std/src/
openzeppelin-contracts/=solidity/lib/openzeppelin-contracts/
-onflow/random-coin-toss=solidity/lib/random-coin-toss
\ No newline at end of file
+flow-sol-utils=solidity/lib/flow-sol-utils/src/
\ No newline at end of file
diff --git a/solidity/src/MaybeMintERC721.sol b/solidity/src/MaybeMintERC721.sol
index 47c0620..3f44a87 100644
--- a/solidity/src/MaybeMintERC721.sol
+++ b/solidity/src/MaybeMintERC721.sol
@@ -3,7 +3,7 @@ pragma solidity 0.8.24;
import {ERC721} from "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
-import {CadenceArchUtils} from "onflow/random-coin-toss/solidity/src/CadenceArchUtils.sol";
+import {CadenceArchUtils} from "flow-sol-utils/cadence-arch/CadenceArchUtils.sol";
/**
* @title MaybeMintERC721
From d203cc90bf760a36eeb35cd807d6a12f643196cb Mon Sep 17 00:00:00 2001
From: Giovanni Sanchez <108043524+sisyphusSmiling@users.noreply.github.com>
Date: Thu, 7 Nov 2024 14:59:47 -0700
Subject: [PATCH 20/20] fix failing Cadence tests & remove debug tests
---
cadence/tests/evm_revertible_random_tests.cdc | 64 -------------------
.../tests/scripts/evm_revertible_random.cdc | 16 -----
cadence/tests/test_helpers.cdc | 10 +--
cadence/tests/wrap_and_mint_tests.cdc | 22 ++++---
.../src/test/TestCadenceRandomConsumer.sol | 29 ---------
5 files changed, 14 insertions(+), 127 deletions(-)
delete mode 100644 cadence/tests/evm_revertible_random_tests.cdc
delete mode 100644 cadence/tests/scripts/evm_revertible_random.cdc
delete mode 100644 solidity/src/test/TestCadenceRandomConsumer.sol
diff --git a/cadence/tests/evm_revertible_random_tests.cdc b/cadence/tests/evm_revertible_random_tests.cdc
deleted file mode 100644
index 8ae3dac..0000000
--- a/cadence/tests/evm_revertible_random_tests.cdc
+++ /dev/null
@@ -1,64 +0,0 @@
-import Test
-import BlockchainHelpers
-import "test_helpers.cdc"
-
-import "EVM"
-
-access(all) let serviceAccount = Test.serviceAccount()
-
-access(all) var coaAddress: String = ""
-access(all) var testAddress: String = ""
-
-access(all)
-fun setup() {
- // Create & fund a CadenceOwnedAccount
- let coaRes = executeTransaction(
- "./transactions/create_coa.cdc",
- [100.0],
- serviceAccount
- )
- Test.expect(coaRes, Test.beSucceeded())
-
- // Extract COA address from event
- let coaEvts = Test.eventsOfType(Type())
- let coaEvt = coaEvts[0] as! EVM.CadenceOwnedAccountCreated
- coaAddress = coaEvt.address
- log("COA address: ".concat(coaAddress))
-
- // Deploy WFLOW
- let testDeployRes = executeTransaction(
- "./transactions/deploy.cdc",
- [testBytecode, UInt64(15_000_000), 0.0],
- serviceAccount
- )
- Test.expect(testDeployRes, Test.beSucceeded())
-
- // Extract test address from event
- var txnExecEvts = Test.eventsOfType(Type())
- let testEvt = txnExecEvts[2] as! EVM.TransactionExecuted
- testAddress = testEvt.contractAddress
-
- log("Test address: ".concat(testAddress))
-}
-
-access(all)
-fun testGetRevertibleRandomSucceeds() {
- let a = getEVMRevertibleRandom(coaHost: serviceAccount.address, testAddress: EVM.addressFromString(testAddress))
- moveBlock()
- let b = getEVMRevertibleRandom(coaHost: serviceAccount.address, testAddress: EVM.addressFromString(testAddress))
- moveBlock()
- let c = getEVMRevertibleRandom(coaHost: serviceAccount.address, testAddress: EVM.addressFromString(testAddress))
- moveBlock()
- let d = getEVMRevertibleRandom(coaHost: serviceAccount.address, testAddress: EVM.addressFromString(testAddress))
- moveBlock()
- let e = getEVMRevertibleRandom(coaHost: serviceAccount.address, testAddress: EVM.addressFromString(testAddress))
- moveBlock()
- let f = getEVMRevertibleRandom(coaHost: serviceAccount.address, testAddress: EVM.addressFromString(testAddress))
- log(String.join([a.toString(), b.toString(), c.toString(), d.toString(), e.toString(), f.toString()], separator: ", "))
- // Test.assert(a != b || a != c || b != c, message: "getEVMRevertibleRandom should return different values")
-}
-
-access(all)
-fun getEVMRevertibleRandom(coaHost: Address, testAddress: EVM.EVMAddress): UInt64 {
- return 0
-}
\ No newline at end of file
diff --git a/cadence/tests/scripts/evm_revertible_random.cdc b/cadence/tests/scripts/evm_revertible_random.cdc
deleted file mode 100644
index 2f0beab..0000000
--- a/cadence/tests/scripts/evm_revertible_random.cdc
+++ /dev/null
@@ -1,16 +0,0 @@
-import "EVM"
-
-access(all)
-fun main(coaHost: Address, testAddress: EVM.EVMAddress): UInt64 {
- let coa = getAuthAccount(coaHost).storage
- .borrow(from: /storage/evm)!
- let res = coa.call(
- to: testAddress,
- data: EVM.encodeABIWithSignature("getRevertibleRandomInRange(uint64,uint64)", [UInt64(0), UInt64(1000)]),
- gasLimit: 15_000_000,
- value: EVM.Balance(attoflow: 0)
- )
- assert(res.status == EVM.Status.successful, message: "getRevertibleRandomInRange failed")
- let decoded = EVM.decodeABI(types: [Type()], data: res.data)
- return decoded[0] as! UInt64
-}
diff --git a/cadence/tests/test_helpers.cdc b/cadence/tests/test_helpers.cdc
index 8fe156d..43607aa 100644
--- a/cadence/tests/test_helpers.cdc
+++ b/cadence/tests/test_helpers.cdc
@@ -1,9 +1,8 @@
import Test
// Bytecode constants
-access(all) let wflowBytecode = "6080604052600436106100ae5763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166306fdde0381146100b8578063095ea7b31461014257806318160ddd1461017a57806323b872dd146101a15780632e1a7d4d146101cb578063313ce567146101e357806370a082311461020e57806395d89b411461022f578063a9059cbb14610244578063d0e30db0146100ae578063dd62ed3e14610268575b6100b661028f565b005b3480156100c457600080fd5b506100cd6102e7565b6040805160208082528351818301528351919283929083019185019080838360005b838110156101075781810151838201526020016100ef565b50505050905090810190601f1680156101345780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561014e57600080fd5b50610166600160a060020a0360043516602435610375565b604080519115158252519081900360200190f35b34801561018657600080fd5b5061018f6103df565b60408051918252519081900360200190f35b3480156101ad57600080fd5b50610166600160a060020a03600435811690602435166044356103ed565b3480156101d757600080fd5b506100b6600435610533565b3480156101ef57600080fd5b506101f86105e3565b6040805160ff9092168252519081900360200190f35b34801561021a57600080fd5b5061018f600160a060020a03600435166105ec565b34801561023b57600080fd5b506100cd6105fe565b34801561025057600080fd5b50610166600160a060020a0360043516602435610658565b34801561027457600080fd5b5061018f600160a060020a036004358116906024351661066c565b600160a060020a033316600081815260036020908152604091829020805434908101909155825190815291517fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c9281900390910190a2565b6000805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152929183018282801561036d5780601f106103425761010080835404028352916020019161036d565b820191906000526020600020905b81548152906001019060200180831161035057829003601f168201915b505050505081565b600160a060020a03338116600081815260046020908152604080832094871680845294825280832086905580518681529051929493927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925929181900390910190a350600192915050565b600160a060020a0330163190565b600160a060020a03831660009081526003602052604081205482111561041257600080fd5b33600160a060020a031684600160a060020a03161415801561045c5750600160a060020a038085166000908152600460209081526040808320339094168352929052205460001914155b156104c257600160a060020a038085166000908152600460209081526040808320339094168352929052205482111561049457600080fd5b600160a060020a03808516600090815260046020908152604080832033909416835292905220805483900390555b600160a060020a03808516600081815260036020908152604080832080548890039055938716808352918490208054870190558351868152935191937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929081900390910190a35060019392505050565b600160a060020a03331660009081526003602052604090205481111561055857600080fd5b600160a060020a033316600081815260036020526040808220805485900390555183156108fc0291849190818181858888f193505050501580156105a0573d6000803e3d6000fd5b50604080518281529051600160a060020a033316917f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65919081900360200190a250565b60025460ff1681565b60036020526000908152604090205481565b60018054604080516020600284861615610100026000190190941693909304601f8101849004840282018401909252818152929183018282801561036d5780601f106103425761010080835404028352916020019161036d565b60006106653384846103ed565b9392505050565b6004602090815260009283526040808420909152908252902054815600a165627a7a72305820e1e0e82b179f331bf99f3294d4266cb1da578c59c07c2de6693f8cb10226617a0029"
-access(all) let erc721Bytecode = "60806040523480156200001157600080fd5b506040516200181b3803806200181b833981016040819052620000349162000208565b338585600062000045838262000332565b50600162000054828262000332565b5050506001600160a01b0381166200008657604051631e4fbdf760e01b81526000600482015260240160405180910390fd5b6200009181620000d1565b50600780546001600160a01b039485166001600160a01b0319918216179091556008929092556009805491909316911617905550506000600a55620003fe565b600680546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200014b57600080fd5b81516001600160401b038082111562000168576200016862000123565b604051601f8301601f19908116603f0116810190828211818310171562000193576200019362000123565b8160405283815260209250866020858801011115620001b157600080fd5b600091505b83821015620001d55785820183015181830184015290820190620001b6565b6000602085830101528094505050505092915050565b80516001600160a01b03811681146200020357600080fd5b919050565b600080600080600060a086880312156200022157600080fd5b85516001600160401b03808211156200023957600080fd5b6200024789838a0162000139565b965060208801519150808211156200025e57600080fd5b506200026d8882890162000139565b9450506200027e60408701620001eb565b9250606086015191506200029560808701620001eb565b90509295509295909350565b600181811c90821680620002b657607f821691505b602082108103620002d757634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200032d576000816000526020600020601f850160051c81016020861015620003085750805b601f850160051c820191505b81811015620003295782815560010162000314565b5050505b505050565b81516001600160401b038111156200034e576200034e62000123565b62000366816200035f8454620002a1565b84620002dd565b602080601f8311600181146200039e5760008415620003855750858301515b600019600386901b1c1916600185901b17855562000329565b600085815260208120601f198616915b82811015620003cf57888601518255948401946001909101908401620003ae565b5085821015620003ee5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b61140d806200040e6000396000f3fe608060405234801561001057600080fd5b50600436106101375760003560e01c806370a08231116100b8578063a22cb4651161007c578063a22cb4651461026b578063b88d4fde1461027e578063bdb4b84814610291578063c87b56dd1461029a578063e985e9c5146102ad578063f2fde38b146102c057600080fd5b806370a0823114610224578063715018a6146102375780638bca6d161461023f5780638da5cb5b1461025257806395d89b411461026357600080fd5b806318160ddd116100ff57806318160ddd146101c157806323b872dd146101d857806338af3eed146101eb57806342842e0e146101fe5780636352211e1461021157600080fd5b806301ffc9a71461013c57806306fdde0314610164578063081812fc14610179578063095ea7b3146101a45780631249c58b146101b9575b600080fd5b61014f61014a366004610fb5565b6102d3565b60405190151581526020015b60405180910390f35b61016c610325565b60405161015b9190611022565b61018c610187366004611035565b6103b7565b6040516001600160a01b03909116815260200161015b565b6101b76101b236600461106a565b6103e0565b005b6101b76103ef565b6101ca600a5481565b60405190815260200161015b565b6101b76101e6366004611094565b6103f9565b60095461018c906001600160a01b031681565b6101b761020c366004611094565b610489565b61018c61021f366004611035565b6104a9565b6101ca6102323660046110d0565b6104b4565b6101b76104fc565b60075461018c906001600160a01b031681565b6006546001600160a01b031661018c565b61016c61050e565b6101b76102793660046110f9565b61051d565b6101b761028c366004611146565b610528565b6101ca60085481565b61016c6102a8366004611035565b610540565b61014f6102bb366004611222565b6105b5565b6101b76102ce3660046110d0565b6105e3565b60006001600160e01b031982166380ac58cd60e01b148061030457506001600160e01b03198216635b5e139f60e01b145b8061031f57506301ffc9a760e01b6001600160e01b03198316145b92915050565b60606000805461033490611255565b80601f016020809104026020016040519081016040528092919081815260200182805461036090611255565b80156103ad5780601f10610382576101008083540402835291602001916103ad565b820191906000526020600020905b81548152906001019060200180831161039057829003601f168201915b5050505050905090565b60006103c282610621565b506000828152600460205260409020546001600160a01b031661031f565b6103eb82823361065a565b5050565b6103f7610667565b565b6001600160a01b03821661042857604051633250574960e11b8152600060048201526024015b60405180910390fd5b6000610435838333610746565b9050836001600160a01b0316816001600160a01b031614610483576040516364283d7b60e01b81526001600160a01b038086166004830152602482018490528216604482015260640161041f565b50505050565b6104a483838360405180602001604052806000815250610528565b505050565b600061031f82610621565b60006001600160a01b0382166104e0576040516322718ad960e21b81526000600482015260240161041f565b506001600160a01b031660009081526003602052604090205490565b61050461083f565b6103f7600061086c565b60606001805461033490611255565b6103eb3383836108be565b6105338484846103f9565b610483338585858561095d565b606061054b82610621565b50600061056360408051602081019091526000815290565b9050600081511161058357604051806020016040528060008152506105ae565b8061058d84610a88565b60405160200161059e92919061128f565b6040516020818303038152906040525b9392505050565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b6105eb61083f565b6001600160a01b03811661061557604051631e4fbdf760e01b81526000600482015260240161041f565b61061e8161086c565b50565b6000818152600260205260408120546001600160a01b03168061031f57604051637e27328960e01b81526004810184905260240161041f565b6104a48383836001610b1b565b61066f610c21565b6007546009546008546040516323b872dd60e01b81523360048201526001600160a01b03928316602482015260448101919091529116906323b872dd906064016020604051808303816000875af19250505080156106ea575060408051601f3d908101601f191682019092526106e7918101906112be565b60015b6107245760075460085460405163760a9bc360e11b81526001600160a01b039092166004830152336024830152604482015260640161041f565b50600a8054906000610735836112db565b91905055506103f733600a54610c62565b6000828152600260205260408120546001600160a01b039081169083161561077357610773818486610cc7565b6001600160a01b038116156107b157610790600085600080610b1b565b6001600160a01b038116600090815260036020526040902080546000190190555b6001600160a01b038516156107e0576001600160a01b0385166000908152600360205260409020805460010190555b60008481526002602052604080822080546001600160a01b0319166001600160a01b0389811691821790925591518793918516917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4949350505050565b6006546001600160a01b031633146103f75760405163118cdaa760e01b815233600482015260240161041f565b600680546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6001600160a01b0382166108f057604051630b61174360e31b81526001600160a01b038316600482015260240161041f565b6001600160a01b03838116600081815260056020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b6001600160a01b0383163b15610a8157604051630a85bd0160e11b81526001600160a01b0384169063150b7a029061099f908890889087908790600401611302565b6020604051808303816000875af19250505080156109da575060408051601f3d908101601f191682019092526109d79181019061133f565b60015b610a43573d808015610a08576040519150601f19603f3d011682016040523d82523d6000602084013e610a0d565b606091505b508051600003610a3b57604051633250574960e11b81526001600160a01b038516600482015260240161041f565b805181602001fd5b6001600160e01b03198116630a85bd0160e11b14610a7f57604051633250574960e11b81526001600160a01b038516600482015260240161041f565b505b5050505050565b60606000610a9583610d2b565b600101905060008167ffffffffffffffff811115610ab557610ab5611130565b6040519080825280601f01601f191660200182016040528015610adf576020820181803683370190505b5090508181016020015b600019016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a8504945084610ae957509392505050565b8080610b2f57506001600160a01b03821615155b15610bf1576000610b3f84610621565b90506001600160a01b03831615801590610b6b5750826001600160a01b0316816001600160a01b031614155b8015610b7e5750610b7c81846105b5565b155b15610ba75760405163a9fbf51f60e01b81526001600160a01b038416600482015260240161041f565b8115610bef5783856001600160a01b0316826001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45b505b5050600090815260046020526040902080546001600160a01b0319166001600160a01b0392909216919091179055565b6000610c2b610e03565b9050610c3860028261135c565b67ffffffffffffffff1660010361061e576040516351d099d960e11b815260040160405180910390fd5b6001600160a01b038216610c8c57604051633250574960e11b81526000600482015260240161041f565b6000610c9a83836000610746565b90506001600160a01b038116156104a4576040516339e3563760e11b81526000600482015260240161041f565b610cd2838383610f3c565b6104a4576001600160a01b038316610d0057604051637e27328960e01b81526004810182905260240161041f565b60405163177e802f60e01b81526001600160a01b03831660048201526024810182905260440161041f565b60008072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b8310610d6a5772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6d04ee2d6d415b85acef81000000008310610d96576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc100008310610db457662386f26fc10000830492506010015b6305f5e1008310610dcc576305f5e100830492506008015b6127108310610de057612710830492506004015b60648310610df2576064830492506002015b600a831061031f5760010192915050565b60408051600481526024810182526020810180516001600160e01b0316630382fd5960e51b1790529051600091829182916801000000000000000191610e499190611391565b600060405180830381855afa9150503d8060008114610e84576040519150601f19603f3d011682016040523d82523d6000602084013e610e89565b606091505b509150915081610f1e5760405162461bcd60e51b815260206004820152605460248201527f556e7375636365737366756c2063616c6c20746f20436164656e63652041726360448201527f68207072652d636f6d70696c65207768656e206665746368696e672072657665606482015273393a34b13632903930b73237b690373ab6b132b960611b608482015260a40161041f565b600081806020019051810190610f3491906113ad565b949350505050565b60006001600160a01b03831615801590610f345750826001600160a01b0316846001600160a01b03161480610f765750610f7684846105b5565b80610f345750506000908152600460205260409020546001600160a01b03908116911614919050565b6001600160e01b03198116811461061e57600080fd5b600060208284031215610fc757600080fd5b81356105ae81610f9f565b60005b83811015610fed578181015183820152602001610fd5565b50506000910152565b6000815180845261100e816020860160208601610fd2565b601f01601f19169290920160200192915050565b6020815260006105ae6020830184610ff6565b60006020828403121561104757600080fd5b5035919050565b80356001600160a01b038116811461106557600080fd5b919050565b6000806040838503121561107d57600080fd5b6110868361104e565b946020939093013593505050565b6000806000606084860312156110a957600080fd5b6110b28461104e565b92506110c06020850161104e565b9150604084013590509250925092565b6000602082840312156110e257600080fd5b6105ae8261104e565b801515811461061e57600080fd5b6000806040838503121561110c57600080fd5b6111158361104e565b91506020830135611125816110eb565b809150509250929050565b634e487b7160e01b600052604160045260246000fd5b6000806000806080858703121561115c57600080fd5b6111658561104e565b93506111736020860161104e565b925060408501359150606085013567ffffffffffffffff8082111561119757600080fd5b818701915087601f8301126111ab57600080fd5b8135818111156111bd576111bd611130565b604051601f8201601f19908116603f011681019083821181831017156111e5576111e5611130565b816040528281528a60208487010111156111fe57600080fd5b82602086016020830137600060208483010152809550505050505092959194509250565b6000806040838503121561123557600080fd5b61123e8361104e565b915061124c6020840161104e565b90509250929050565b600181811c9082168061126957607f821691505b60208210810361128957634e487b7160e01b600052602260045260246000fd5b50919050565b600083516112a1818460208801610fd2565b8351908301906112b5818360208801610fd2565b01949350505050565b6000602082840312156112d057600080fd5b81516105ae816110eb565b6000600182016112fb57634e487b7160e01b600052601160045260246000fd5b5060010190565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061133590830184610ff6565b9695505050505050565b60006020828403121561135157600080fd5b81516105ae81610f9f565b600067ffffffffffffffff8084168061138557634e487b7160e01b600052601260045260246000fd5b92169190910692915050565b600082516113a3818460208701610fd2565b9190910192915050565b6000602082840312156113bf57600080fd5b815167ffffffffffffffff811681146105ae57600080fdfea26469706673582212204919ee1872648a1b85d633af14a8f8c7163d176b6699f75fe4e22d677fc562ae64736f6c63430008180033"
-access(all) let testBytecode = "608060405234801561001057600080fd5b50611210806100206000396000f3fe608060405234801561001057600080fd5b50600436106100575760003560e01c80635461f2e41461005c578063bc26d8241461008c578063d59fd63c1461009f578063f8413b07146100c2578063fc177f7f146100d8575b600080fd5b61006f61006a366004610fac565b6100eb565b6040516001600160401b0390911681526020015b60405180910390f35b61006f61009a366004610fe5565b610100565b6100b26100ad366004610fe5565b61010b565b6040519015158152602001610083565b6100ca610189565b604051908152602001610083565b61006f6100e6366004610ffe565b610198565b60006100f783836101ad565b90505b92915050565b60006100fa82610225565b600080610119600184611056565b600054909150811061012e5750600092915050565b600080828154811061014257610142611069565b90600052602060002090600302019050600061015c6102df565b600283015490915060ff16158015610180575081546001600160401b038083169116105b95945050505050565b600061019361040e565b905090565b60006101a584848461054f565b949350505050565b6000806101b861060d565b6040516020016101ca91815260200190565b60408051601f1981840301815282825243602084015292506000910160408051601f1981840301815282820190915260008083526020830152915061021081848461066a565b61021b81878761079d565b9695505050505050565b600080610231836108cc565b60405160200161024391815260200190565b60408051601f198184030181528282526020830186905292506000910160408051601f1981840301815282820190915260008083526020830152915061028a81848461066a565b600061029582610a11565b6040516001600160401b038216815290915086907fe3e452ff947e18cea0f62f23d405e522ac808f69346c5f59ddc4bd722ac10d039060200160405180910390a295945050505050565b60408051600481526024810182526020810180516001600160e01b03166329f43eb360e11b179052905160009182918291680100000000000000019161032591906110af565b600060405180830381855afa9150503d8060008114610360576040519150601f19603f3d011682016040523d82523d6000602084013e610365565b606091505b5091509150816103f85760405162461bcd60e51b815260206004820152604d60248201527f556e7375636365737366756c2063616c6c20746f20436164656e63652041726360448201527f68207072652d636f6d70696c65207768656e206665746368696e6720466c6f7760648201526c08189b1bd8dac81a195a59da1d609a1b608482015260a4015b60405180910390fd5b6000818060200190518101906101a591906110bb565b600180546000918261041f836110df565b919050555060006001549050600060405180606001604052806104406102df565b6001600160401b0390811682524360208084019190915260006040938401819052805460018101825590805284517f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5636003909202918201805467ffffffffffffffff191691909416908117909355848201517f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5648201819055858501517f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e565909201805460ff19169215159290921790915583519283529082015291925083917f7886956edccde10901843c3e51fc26016455e9248e210a29c2a57ead63ad226e910160405180910390a250919050565b60008061055b856108cc565b60405160200161056d91815260200190565b60408051601f198184030181528282526020830188905292506000910160408051601f198184030181528282019091526000808352602083015291506105b481848461066a565b60006105c182888861079d565b6040516001600160401b038216815290915088907fe3e452ff947e18cea0f62f23d405e522ac808f69346c5f59ddc4bd722ac10d039060200160405180910390a2979650505050505050565b600080610618610a6e565b6001600160401b03169050604061062d610a6e565b6001600160401b0316901b176080610643610a6e565b6001600160401b0316901b1760c0610659610a6e565b6001600160401b0316901b17919050565b6010825110156106f05760405162461bcd60e51b815260206004820152604560248201527f4174206c65617374203136206279746573206f6620656e74726f70792073686f60448201527f756c642062652075736564207768656e20696e697469616c697a696e67207468606482015264652050524760d81b608482015260a4016103ef565b600082826040516020016107059291906110f8565b604051602081830303815290604052905060008180519060200120905061074e8160405160200161073891815260200190565b6040516020818303038152906040526000610b89565b6001600160401b03168552604080516020810183905261077f91016040516020818303038152906040526008610b89565b6001600160401b0316602086015261079685610c41565b5050505050565b6000826001600160401b0316826001600160401b0316116108005760405162461bcd60e51b815260206004820152601c60248201527f4d6178206d7573742062652067726561746572207468616e206d696e0000000060448201526064016103ef565b600061080c848461110d565b9050600061081982610cda565b9050600061083460016001600160401b03841681901b611056565b9050600061084483610100611134565b6001600160401b03169050600080600061085d8b610d10565b90505b8481169150866001600160401b0316826001600160401b031611156108b3576001600160401b0386161c82610894816110df565b9350508383036108ae576108a78b610d10565b9050600092505b610860565b6108bd828b611168565b9b9a5050505050505050505050565b6000806108da600184611056565b600054909150811061095f5760405162461bcd60e51b815260206004820152604260248201527f496e76616c69642072657175657374204944202d2076616c756520657863656560448201527f647320746865206e756d626572206f66206578697374696e6720726571756573606482015261747360f01b608482015260a4016103ef565b600080828154811061097357610973611069565b9060005260206000209060030201905061098c81610d72565b60028101805460ff1916600117905580546000906109b2906001600160401b0316610e5b565b82546001840154604080516001600160401b0390931683526020830191909152810182905290915085907f01f207584638dfbb3f1d85bba3809672fcb07a3d2e291308293ba78b7f1984909060600160405180910390a2949350505050565b6000610a1c82610c41565b5080516020820180516001600160401b03808216909452601783901b6a7fffffffffffffff80000016909218601181901c657fffffffffff1618601a83901c643fffffffff1683181892831690520190565b60408051600481526024810182526020810180516001600160e01b0316630382fd5960e51b1790529051600091829182916801000000000000000191610ab491906110af565b600060405180830381855afa9150503d8060008114610aef576040519150601f19603f3d011682016040523d82523d6000602084013e610af4565b606091505b5091509150816103f85760405162461bcd60e51b815260206004820152605460248201527f556e7375636365737366756c2063616c6c20746f20436164656e63652041726360448201527f68207072652d636f6d70696c65207768656e206665746368696e672072657665606482015273393a34b13632903930b73237b690373ab6b132b960611b608482015260a4016103ef565b6000610b96826008611188565b83511015610bdc5760405162461bcd60e51b8152602060048201526013602482015272092dcecc2d8d2c840c4f2e8ca40d8cadccee8d606b1b60448201526064016103ef565b6000805b6008811015610c395784610bf48286611188565b81518110610c0457610c04611069565b602001015160f81c60f81b60f81c60ff166008836001600160401b0316901b1791508080610c31906110df565b915050610be0565b509392505050565b80516001600160401b0316151580610c65575060208101516001600160401b031615155b610cd75760405162461bcd60e51b815260206004820152603860248201527f50524720696e697469616c2073746174652069732030202d206d75737420626560448201527f20696e697469616c697a6564206173206e6f6e2d7a65726f000000000000000060648201526084016103ef565b50565b6000805b6001600160401b038316156100fa576001836001600160401b0316901c92508080610d089061119b565b915050610cde565b600080610d1c83610a11565b6001600160401b031690506040610d3284610a11565b6001600160401b0316901b176080610d4984610a11565b6001600160401b0316901b1760c0610d6084610a11565b6001600160401b0316901b1792915050565b600281015460ff1615610dc75760405162461bcd60e51b815260206004820152601960248201527f5265717565737420616c72656164792066756c66696c6c65640000000000000060448201526064016103ef565b610dcf6102df565b81546001600160401b03918216911610610cd75760405162461bcd60e51b815260206004820152604160248201527f43616e6e6f742066756c66696c6c207265717565737420756e74696c2073756260448201527f73657175656e7420466c6f77206e6574776f726b20626c6f636b2068656967686064820152601d60fa1b608482015260a4016103ef565b6040516001600160401b038216602482015260009081908190680100000000000000019060440160408051601f198184030181529181526020820180516001600160e01b0316633c53afdf60e11b17905251610eb791906110af565b600060405180830381855afa9150503d8060008114610ef2576040519150601f19603f3d011682016040523d82523d6000602084013e610ef7565b606091505b509150915081610f815760405162461bcd60e51b815260206004820152604960248201527f556e7375636365737366756c2063616c6c20746f20436164656e63652041726360448201527f68207072652d636f6d70696c65207768656e206665746368696e672072616e646064820152686f6d20736f7572636560b81b608482015260a4016103ef565b60008180602001905181019061018091906111c1565b6001600160401b0381168114610cd757600080fd5b60008060408385031215610fbf57600080fd5b8235610fca81610f97565b91506020830135610fda81610f97565b809150509250929050565b600060208284031215610ff757600080fd5b5035919050565b60008060006060848603121561101357600080fd5b83359250602084013561102581610f97565b9150604084013561103581610f97565b809150509250925092565b634e487b7160e01b600052601160045260246000fd5b818103818111156100fa576100fa611040565b634e487b7160e01b600052603260045260246000fd5b6000815160005b818110156110a05760208185018101518683015201611086565b50600093019283525090919050565b60006100f7828461107f565b6000602082840312156110cd57600080fd5b81516110d881610f97565b9392505050565b6000600182016110f1576110f1611040565b5060010190565b60006101a5611107838661107f565b8461107f565b6001600160401b0382811682821603908082111561112d5761112d611040565b5092915050565b60006001600160401b038084168061115c57634e487b7160e01b600052601260045260246000fd5b92169190910492915050565b6001600160401b0381811683821601908082111561112d5761112d611040565b808201808211156100fa576100fa611040565b60006001600160401b038083168181036111b7576111b7611040565b6001019392505050565b6000602082840312156111d357600080fd5b505191905056fea2646970667358221220f8c9a068ce5c9c1b3f61e3676f66b60a38347f8e7f4830594074a9377b82688564736f6c63430008130033"
+access(all) let wflowBytecode = "60c0604052600c60808190526b5772617070656420466c6f7760a01b60a090815261002d916000919061007a565b506040805180820190915260058082526457464c4f5760d81b602090920191825261005a9160019161007a565b506002805460ff1916601217905534801561007457600080fd5b50610115565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106100bb57805160ff19168380011785556100e8565b828001600101855582156100e8579182015b828111156100e85782518255916020019190600101906100cd565b506100f49291506100f8565b5090565b61011291905b808211156100f457600081556001016100fe565b90565b6106e3806101246000396000f3fe60806040526004361061009c5760003560e01c8063313ce56711610064578063313ce5671461021157806370a082311461023c57806395d89b411461026f578063a9059cbb14610284578063d0e30db01461009c578063dd62ed3e146102bd5761009c565b806306fdde03146100a6578063095ea7b31461013057806318160ddd1461017d57806323b872dd146101a45780632e1a7d4d146101e7575b6100a46102f8565b005b3480156100b257600080fd5b506100bb610347565b6040805160208082528351818301528351919283929083019185019080838360005b838110156100f55781810151838201526020016100dd565b50505050905090810190601f1680156101225780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561013c57600080fd5b506101696004803603604081101561015357600080fd5b506001600160a01b0381351690602001356103d5565b604080519115158252519081900360200190f35b34801561018957600080fd5b5061019261043b565b60408051918252519081900360200190f35b3480156101b057600080fd5b50610169600480360360608110156101c757600080fd5b506001600160a01b0381358116916020810135909116906040013561043f565b3480156101f357600080fd5b506100a46004803603602081101561020a57600080fd5b5035610573565b34801561021d57600080fd5b50610226610608565b6040805160ff9092168252519081900360200190f35b34801561024857600080fd5b506101926004803603602081101561025f57600080fd5b50356001600160a01b0316610611565b34801561027b57600080fd5b506100bb610623565b34801561029057600080fd5b50610169600480360360408110156102a757600080fd5b506001600160a01b03813516906020013561067d565b3480156102c957600080fd5b50610192600480360360408110156102e057600080fd5b506001600160a01b0381358116916020013516610691565b33600081815260036020908152604091829020805434908101909155825190815291517fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c9281900390910190a2565b6000805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156103cd5780601f106103a2576101008083540402835291602001916103cd565b820191906000526020600020905b8154815290600101906020018083116103b057829003601f168201915b505050505081565b3360008181526004602090815260408083206001600160a01b038716808552908352818420869055815186815291519394909390927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925928290030190a350600192915050565b4790565b6001600160a01b03831660009081526003602052604081205482111561046457600080fd5b6001600160a01b03841633148015906104a257506001600160a01b038416600090815260046020908152604080832033845290915290205460001914155b15610502576001600160a01b03841660009081526004602090815260408083203384529091529020548211156104d757600080fd5b6001600160a01b03841660009081526004602090815260408083203384529091529020805483900390555b6001600160a01b03808516600081815260036020908152604080832080548890039055938716808352918490208054870190558351868152935191937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929081900390910190a35060019392505050565b3360009081526003602052604090205481111561058f57600080fd5b33600081815260036020526040808220805485900390555183156108fc0291849190818181858888f193505050501580156105ce573d6000803e3d6000fd5b5060408051828152905133917f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65919081900360200190a250565b60025460ff1681565b60036020526000908152604090205481565b60018054604080516020600284861615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156103cd5780601f106103a2576101008083540402835291602001916103cd565b600061068a33848461043f565b9392505050565b60046020908152600092835260408084209091529082529020548156fea265627a7a7231582092a6eff3c9232bde55997efc6d8d256f5875b16304694b39e740dcabf78f802964736f6c63430005110032"
+access(all) let erc721Bytecode = "60806040523480156200001157600080fd5b506040516200181b3803806200181b833981016040819052620000349162000208565b338585600062000045838262000332565b50600162000054828262000332565b5050506001600160a01b0381166200008657604051631e4fbdf760e01b81526000600482015260240160405180910390fd5b6200009181620000d1565b50600780546001600160a01b039485166001600160a01b0319918216179091556008929092556009805491909316911617905550506000600a55620003fe565b600680546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200014b57600080fd5b81516001600160401b038082111562000168576200016862000123565b604051601f8301601f19908116603f0116810190828211818310171562000193576200019362000123565b8160405283815260209250866020858801011115620001b157600080fd5b600091505b83821015620001d55785820183015181830184015290820190620001b6565b6000602085830101528094505050505092915050565b80516001600160a01b03811681146200020357600080fd5b919050565b600080600080600060a086880312156200022157600080fd5b85516001600160401b03808211156200023957600080fd5b6200024789838a0162000139565b965060208801519150808211156200025e57600080fd5b506200026d8882890162000139565b9450506200027e60408701620001eb565b9250606086015191506200029560808701620001eb565b90509295509295909350565b600181811c90821680620002b657607f821691505b602082108103620002d757634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200032d576000816000526020600020601f850160051c81016020861015620003085750805b601f850160051c820191505b81811015620003295782815560010162000314565b5050505b505050565b81516001600160401b038111156200034e576200034e62000123565b62000366816200035f8454620002a1565b84620002dd565b602080601f8311600181146200039e5760008415620003855750858301515b600019600386901b1c1916600185901b17855562000329565b600085815260208120601f198616915b82811015620003cf57888601518255948401946001909101908401620003ae565b5085821015620003ee5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b61140d806200040e6000396000f3fe608060405234801561001057600080fd5b50600436106101375760003560e01c806370a08231116100b8578063a22cb4651161007c578063a22cb4651461026b578063b88d4fde1461027e578063bdb4b84814610291578063c87b56dd1461029a578063e985e9c5146102ad578063f2fde38b146102c057600080fd5b806370a0823114610224578063715018a6146102375780638bca6d161461023f5780638da5cb5b1461025257806395d89b411461026357600080fd5b806318160ddd116100ff57806318160ddd146101c157806323b872dd146101d857806338af3eed146101eb57806342842e0e146101fe5780636352211e1461021157600080fd5b806301ffc9a71461013c57806306fdde0314610164578063081812fc14610179578063095ea7b3146101a45780631249c58b146101b9575b600080fd5b61014f61014a366004610fb5565b6102d3565b60405190151581526020015b60405180910390f35b61016c610325565b60405161015b9190611022565b61018c610187366004611035565b6103b7565b6040516001600160a01b03909116815260200161015b565b6101b76101b236600461106a565b6103e0565b005b6101b76103ef565b6101ca600a5481565b60405190815260200161015b565b6101b76101e6366004611094565b6103f9565b60095461018c906001600160a01b031681565b6101b761020c366004611094565b610489565b61018c61021f366004611035565b6104a9565b6101ca6102323660046110d0565b6104b4565b6101b76104fc565b60075461018c906001600160a01b031681565b6006546001600160a01b031661018c565b61016c61050e565b6101b76102793660046110f9565b61051d565b6101b761028c366004611146565b610528565b6101ca60085481565b61016c6102a8366004611035565b610540565b61014f6102bb366004611222565b6105b5565b6101b76102ce3660046110d0565b6105e3565b60006001600160e01b031982166380ac58cd60e01b148061030457506001600160e01b03198216635b5e139f60e01b145b8061031f57506301ffc9a760e01b6001600160e01b03198316145b92915050565b60606000805461033490611255565b80601f016020809104026020016040519081016040528092919081815260200182805461036090611255565b80156103ad5780601f10610382576101008083540402835291602001916103ad565b820191906000526020600020905b81548152906001019060200180831161039057829003601f168201915b5050505050905090565b60006103c282610621565b506000828152600460205260409020546001600160a01b031661031f565b6103eb82823361065a565b5050565b6103f7610667565b565b6001600160a01b03821661042857604051633250574960e11b8152600060048201526024015b60405180910390fd5b6000610435838333610746565b9050836001600160a01b0316816001600160a01b031614610483576040516364283d7b60e01b81526001600160a01b038086166004830152602482018490528216604482015260640161041f565b50505050565b6104a483838360405180602001604052806000815250610528565b505050565b600061031f82610621565b60006001600160a01b0382166104e0576040516322718ad960e21b81526000600482015260240161041f565b506001600160a01b031660009081526003602052604090205490565b61050461083f565b6103f7600061086c565b60606001805461033490611255565b6103eb3383836108be565b6105338484846103f9565b610483338585858561095d565b606061054b82610621565b50600061056360408051602081019091526000815290565b9050600081511161058357604051806020016040528060008152506105ae565b8061058d84610a88565b60405160200161059e92919061128f565b6040516020818303038152906040525b9392505050565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b6105eb61083f565b6001600160a01b03811661061557604051631e4fbdf760e01b81526000600482015260240161041f565b61061e8161086c565b50565b6000818152600260205260408120546001600160a01b03168061031f57604051637e27328960e01b81526004810184905260240161041f565b6104a48383836001610b1b565b61066f610c21565b6007546009546008546040516323b872dd60e01b81523360048201526001600160a01b03928316602482015260448101919091529116906323b872dd906064016020604051808303816000875af19250505080156106ea575060408051601f3d908101601f191682019092526106e7918101906112be565b60015b6107245760075460085460405163760a9bc360e11b81526001600160a01b039092166004830152336024830152604482015260640161041f565b50600a8054906000610735836112db565b91905055506103f733600a54610c62565b6000828152600260205260408120546001600160a01b039081169083161561077357610773818486610cc7565b6001600160a01b038116156107b157610790600085600080610b1b565b6001600160a01b038116600090815260036020526040902080546000190190555b6001600160a01b038516156107e0576001600160a01b0385166000908152600360205260409020805460010190555b60008481526002602052604080822080546001600160a01b0319166001600160a01b0389811691821790925591518793918516917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4949350505050565b6006546001600160a01b031633146103f75760405163118cdaa760e01b815233600482015260240161041f565b600680546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6001600160a01b0382166108f057604051630b61174360e31b81526001600160a01b038316600482015260240161041f565b6001600160a01b03838116600081815260056020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b6001600160a01b0383163b15610a8157604051630a85bd0160e11b81526001600160a01b0384169063150b7a029061099f908890889087908790600401611302565b6020604051808303816000875af19250505080156109da575060408051601f3d908101601f191682019092526109d79181019061133f565b60015b610a43573d808015610a08576040519150601f19603f3d011682016040523d82523d6000602084013e610a0d565b606091505b508051600003610a3b57604051633250574960e11b81526001600160a01b038516600482015260240161041f565b805181602001fd5b6001600160e01b03198116630a85bd0160e11b14610a7f57604051633250574960e11b81526001600160a01b038516600482015260240161041f565b505b5050505050565b60606000610a9583610d2b565b600101905060008167ffffffffffffffff811115610ab557610ab5611130565b6040519080825280601f01601f191660200182016040528015610adf576020820181803683370190505b5090508181016020015b600019016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a8504945084610ae957509392505050565b8080610b2f57506001600160a01b03821615155b15610bf1576000610b3f84610621565b90506001600160a01b03831615801590610b6b5750826001600160a01b0316816001600160a01b031614155b8015610b7e5750610b7c81846105b5565b155b15610ba75760405163a9fbf51f60e01b81526001600160a01b038416600482015260240161041f565b8115610bef5783856001600160a01b0316826001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45b505b5050600090815260046020526040902080546001600160a01b0319166001600160a01b0392909216919091179055565b6000610c2b610e03565b9050610c3860028261135c565b67ffffffffffffffff1660010361061e576040516351d099d960e11b815260040160405180910390fd5b6001600160a01b038216610c8c57604051633250574960e11b81526000600482015260240161041f565b6000610c9a83836000610746565b90506001600160a01b038116156104a4576040516339e3563760e11b81526000600482015260240161041f565b610cd2838383610f3c565b6104a4576001600160a01b038316610d0057604051637e27328960e01b81526004810182905260240161041f565b60405163177e802f60e01b81526001600160a01b03831660048201526024810182905260440161041f565b60008072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b8310610d6a5772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6d04ee2d6d415b85acef81000000008310610d96576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc100008310610db457662386f26fc10000830492506010015b6305f5e1008310610dcc576305f5e100830492506008015b6127108310610de057612710830492506004015b60648310610df2576064830492506002015b600a831061031f5760010192915050565b60408051600481526024810182526020810180516001600160e01b0316630382fd5960e51b1790529051600091829182916801000000000000000191610e499190611391565b600060405180830381855afa9150503d8060008114610e84576040519150601f19603f3d011682016040523d82523d6000602084013e610e89565b606091505b509150915081610f1e5760405162461bcd60e51b815260206004820152605460248201527f556e7375636365737366756c2063616c6c20746f20436164656e63652041726360448201527f68207072652d636f6d70696c65207768656e206665746368696e672072657665606482015273393a34b13632903930b73237b690373ab6b132b960611b608482015260a40161041f565b600081806020019051810190610f3491906113ad565b949350505050565b60006001600160a01b03831615801590610f345750826001600160a01b0316846001600160a01b03161480610f765750610f7684846105b5565b80610f345750506000908152600460205260409020546001600160a01b03908116911614919050565b6001600160e01b03198116811461061e57600080fd5b600060208284031215610fc757600080fd5b81356105ae81610f9f565b60005b83811015610fed578181015183820152602001610fd5565b50506000910152565b6000815180845261100e816020860160208601610fd2565b601f01601f19169290920160200192915050565b6020815260006105ae6020830184610ff6565b60006020828403121561104757600080fd5b5035919050565b80356001600160a01b038116811461106557600080fd5b919050565b6000806040838503121561107d57600080fd5b6110868361104e565b946020939093013593505050565b6000806000606084860312156110a957600080fd5b6110b28461104e565b92506110c06020850161104e565b9150604084013590509250925092565b6000602082840312156110e257600080fd5b6105ae8261104e565b801515811461061e57600080fd5b6000806040838503121561110c57600080fd5b6111158361104e565b91506020830135611125816110eb565b809150509250929050565b634e487b7160e01b600052604160045260246000fd5b6000806000806080858703121561115c57600080fd5b6111658561104e565b93506111736020860161104e565b925060408501359150606085013567ffffffffffffffff8082111561119757600080fd5b818701915087601f8301126111ab57600080fd5b8135818111156111bd576111bd611130565b604051601f8201601f19908116603f011681019083821181831017156111e5576111e5611130565b816040528281528a60208487010111156111fe57600080fd5b82602086016020830137600060208483010152809550505050505092959194509250565b6000806040838503121561123557600080fd5b61123e8361104e565b915061124c6020840161104e565b90509250929050565b600181811c9082168061126957607f821691505b60208210810361128957634e487b7160e01b600052602260045260246000fd5b50919050565b600083516112a1818460208801610fd2565b8351908301906112b5818360208801610fd2565b01949350505050565b6000602082840312156112d057600080fd5b81516105ae816110eb565b6000600182016112fb57634e487b7160e01b600052601160045260246000fd5b5060010190565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061133590830184610ff6565b9695505050505050565b60006020828403121561135157600080fd5b81516105ae81610f9f565b600067ffffffffffffffff8084168061138557634e487b7160e01b600052601260045260246000fd5b92169190910692915050565b600082516113a3818460208701610fd2565b9190910192915050565b6000602082840312156113bf57600080fd5b815167ffffffffffffffff811681146105ae57600080fdfea2646970667358221220859d8cb88597efba0ae5690919e0bd43747ee03f464470c2b6f1c0b3f9bb454f64736f6c63430008180033"
/* --- Getters --- */
@@ -17,11 +16,6 @@ fun getERC721Bytecode(): String {
return erc721Bytecode
}
-access(all)
-fun getTestBytecode(): String {
- return testBytecode
-}
-
access(all)
fun moveBlock() {
let res = _executeTransaction(
diff --git a/cadence/tests/wrap_and_mint_tests.cdc b/cadence/tests/wrap_and_mint_tests.cdc
index fde9ff2..d8120b4 100644
--- a/cadence/tests/wrap_and_mint_tests.cdc
+++ b/cadence/tests/wrap_and_mint_tests.cdc
@@ -24,7 +24,6 @@ fun setup() {
let coaEvts = Test.eventsOfType(Type())
let coaEvt = coaEvts[0] as! EVM.CadenceOwnedAccountCreated
coaAddress = coaEvt.address
- log("COA address: ".concat(coaAddress))
// Deploy WFLOW
let wflowDeployRes = executeTransaction(
@@ -52,7 +51,7 @@ fun setup() {
constructorArgs
))
// Append the encoded constructor args to the compiled bytecode
- let finalBytecode = getERC721Bytecode().concat(argsBytecode)
+ let finalBytecode = String.join([getERC721Bytecode(), argsBytecode], separator: "")
let erc721DeployRes = executeTransaction(
"./transactions/deploy.cdc",
[finalBytecode, UInt64(15_000_000), 0.0],
@@ -64,9 +63,6 @@ fun setup() {
txnExecEvts = Test.eventsOfType(Type())
let erc721Evt = txnExecEvts[3] as! EVM.TransactionExecuted
erc721Address = erc721Evt.contractAddress
-
- log("WFLOW address: ".concat(wflowAddress))
- log("ERC721 address: ".concat(erc721Address))
}
access(all)
@@ -74,15 +70,21 @@ fun testWrapAndMintSucceeds() {
let user = Test.createAccount()
mintFlow(to: user, amount: 10.0)
- wrapAndMintUntilSuccess(signer: user, wflow: wflowAddress, erc721: erc721Address)
+ // Executes the wrap_and_mint.cdc transaction
+ // - Creates a COA
+ // - Funds the COA with FLOW to cover mint cost
+ // - Wraps FLOW as WFLOW
+ // - Approves ERC721 contract to mint
+ // - Mints ERC721 <- may fail so we retry here until success (can't mock CadenceArch calls in Cadence tests atm)
+ wrapAndMintUntilSuccess(iter: 5, signer: user, wflow: wflowAddress, erc721: erc721Address)
}
access(all)
-fun wrapAndMintUntilSuccess(signer: Test.TestAccount, wflow: String, erc721: String) {
+fun wrapAndMintUntilSuccess(iter: Int, signer: Test.TestAccount, wflow: String, erc721: String) {
var i = 0
var success = false
- while i < 50 {
- let res: Test.TransactionResult = executeTransaction(
+ while i < iter {
+ let res = executeTransaction(
"../transactions/bundled/wrap_and_mint.cdc",
[wflow, erc721],
signer
@@ -95,5 +97,5 @@ fun wrapAndMintUntilSuccess(signer: Test.TestAccount, wflow: String, erc721: Str
moveBlock()
}
}
- Test.assertEqual(true, success)
+ Test.assert(success)
}
\ No newline at end of file
diff --git a/solidity/src/test/TestCadenceRandomConsumer.sol b/solidity/src/test/TestCadenceRandomConsumer.sol
deleted file mode 100644
index 950b6f2..0000000
--- a/solidity/src/test/TestCadenceRandomConsumer.sol
+++ /dev/null
@@ -1,29 +0,0 @@
-// SPDX-License-Identifier: Unlicense
-pragma solidity 0.8.19;
-
-import {CadenceRandomConsumer} from "onflow/random-coin-toss/solidity/src/CadenceRandomConsumer.sol";
-
-/**
- * @dev This contract extends CadenceRandomConsumer to expose internal functions for testing.
- */
-contract TestCadenceRandomConsumer is CadenceRandomConsumer {
- // Expose internal _getRevertibleRandomInRange function for testing
- function getRevertibleRandomInRange(uint64 min, uint64 max) public view returns (uint64) {
- return _getRevertibleRandomInRange(min, max);
- }
-
- // Expose internal _requestRandomness function for testing
- function requestRandomness() public returns (uint256) {
- return _requestRandomness();
- }
-
- // Expose internal _fulfillRandomRequest function for testing
- function fulfillRandomRequest(uint256 requestId) public returns (uint64) {
- return _fulfillRandomRequest(requestId);
- }
-
- // Expose internal _fulfillRandomInRange function for testing
- function fulfillRandomInRange(uint256 requestId, uint64 min, uint64 max) public returns (uint64) {
- return _fulfillRandomInRange(requestId, min, max);
- }
-}