diff --git a/contracts/Aavegotchi/Diamond.sol b/contracts/Aavegotchi/Diamond.sol
new file mode 100644
index 000000000..4376428e3
--- /dev/null
+++ b/contracts/Aavegotchi/Diamond.sol
@@ -0,0 +1,44 @@
+import {LibDiamond} from "../shared/libraries/LibDiamond.sol";
+import {DiamondCutFacet} from "../shared/facets/DiamondCutFacet.sol";
+import {DiamondLoupeFacet} from "../shared/facets/DiamondLoupeFacet.sol";
+import {OwnershipFacet} from "../shared/facets/OwnershipFacet.sol";
+
+contract Diamond {
+ constructor(address _contractOwner) {
+ LibDiamond.setContractOwner(_contractOwner);
+ LibDiamond.addDiamondFunctions(address(new DiamondCutFacet()), address(new DiamondLoupeFacet()), address(new OwnershipFacet()));
+ }
+
+ //an immutable function that returns the diamondCut, diamondLoupe, and ownership facet addresses for testing
+
+ function getDefaultFacetAddresses() public view returns (address diamondCut, address diamondLoupe, address ownership) {
+ LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();
+ diamondCut = ds.facetAddresses[0];
+ diamondLoupe = ds.facetAddresses[1];
+ ownership = ds.facetAddresses[2];
+ }
+
+ // Find facet for function that is called and execute the
+ // function if a facet is found and return any value.
+ fallback() external payable {
+ LibDiamond.DiamondStorage storage ds;
+ bytes32 position = LibDiamond.DIAMOND_STORAGE_POSITION;
+ assembly {
+ ds.slot := position
+ }
+ address facet = ds.selectorToFacetAndPosition[msg.sig].facetAddress;
+ require(facet != address(0), "Diamond: Function does not exist");
+ assembly {
+ calldatacopy(0, 0, calldatasize())
+ let result := delegatecall(gas(), facet, 0, calldatasize(), 0, 0)
+ returndatacopy(0, 0, returndatasize())
+ switch result
+ case 0 {
+ revert(0, returndatasize())
+ }
+ default {
+ return(0, returndatasize())
+ }
+ }
+ }
+}
diff --git a/contracts/Aavegotchi/ForgeDiamond/ForgeDiamond.sol b/contracts/Aavegotchi/ForgeDiamond/ForgeDiamond.sol
index e6d51891a..98bd227b2 100644
--- a/contracts/Aavegotchi/ForgeDiamond/ForgeDiamond.sol
+++ b/contracts/Aavegotchi/ForgeDiamond/ForgeDiamond.sol
@@ -17,11 +17,15 @@ contract ForgeDiamond {
address _contractOwner,
address _diamondCutFacet,
address _diaomondLoupeFacet,
- address _ownershipFacet
+ address _ownershipFacet,
+ address _aavegotchiDiamond,
+ address wearableDiamond
) {
ForgeLibDiamond.setContractOwner(_contractOwner);
ForgeLibDiamond.addDiamondFunctions(_diamondCutFacet, _diaomondLoupeFacet, _ownershipFacet);
ForgeLibDiamond.DiamondStorage storage ds = ForgeLibDiamond.diamondStorage();
+ ds.AAVEGOTCHI_DIAMOND = _aavegotchiDiamond;
+ ds.WEARABLE_DIAMOND = wearableDiamond;
ds.supportedInterfaces[0xd9b67a26] = true; //erc1155
}
diff --git a/contracts/Aavegotchi/ForgeDiamond/facets/ForgeFacet.sol b/contracts/Aavegotchi/ForgeDiamond/facets/ForgeFacet.sol
index 29991412f..309e8ca40 100644
--- a/contracts/Aavegotchi/ForgeDiamond/facets/ForgeFacet.sol
+++ b/contracts/Aavegotchi/ForgeDiamond/facets/ForgeFacet.sol
@@ -46,24 +46,24 @@ contract ForgeFacet is Modifiers {
}
// External contracts
- function aavegotchiGameFacet() internal pure returns (AavegotchiGameFacet facet) {
- facet = AavegotchiGameFacet(ForgeLibDiamond.AAVEGOTCHI_DIAMOND);
+ function aavegotchiGameFacet() internal view returns (AavegotchiGameFacet facet) {
+ facet = AavegotchiGameFacet(ForgeLibDiamond.AAVEGOTCHI_DIAMOND());
}
- function aavegotchiFacet() internal pure returns (AavegotchiFacet facet) {
- facet = AavegotchiFacet(ForgeLibDiamond.AAVEGOTCHI_DIAMOND);
+ function aavegotchiFacet() internal view returns (AavegotchiFacet facet) {
+ facet = AavegotchiFacet(ForgeLibDiamond.AAVEGOTCHI_DIAMOND());
}
- function itemsFacet() internal pure returns (ItemsFacet facet) {
- facet = ItemsFacet(ForgeLibDiamond.AAVEGOTCHI_DIAMOND);
+ function itemsFacet() internal view returns (ItemsFacet facet) {
+ facet = ItemsFacet(ForgeLibDiamond.AAVEGOTCHI_DIAMOND());
}
- function wearablesFacet() internal pure returns (WearablesFacet facet) {
- facet = WearablesFacet(ForgeLibDiamond.WEARABLE_DIAMOND);
+ function wearablesFacet() internal view returns (WearablesFacet facet) {
+ facet = WearablesFacet(ForgeLibDiamond.WEARABLE_DIAMOND());
}
- function lendingGetterAndSetterFacet() internal pure returns (LendingGetterAndSetterFacet facet) {
- facet = LendingGetterAndSetterFacet(ForgeLibDiamond.AAVEGOTCHI_DIAMOND);
+ function lendingGetterAndSetterFacet() internal view returns (LendingGetterAndSetterFacet facet) {
+ facet = LendingGetterAndSetterFacet(ForgeLibDiamond.AAVEGOTCHI_DIAMOND());
}
function gltrContract() internal view returns (IERC20 token) {
@@ -288,11 +288,7 @@ contract ForgeFacet is Modifiers {
}
}
- function _forge(
- uint256 itemId,
- uint256 gotchiId,
- uint40 _gltr
- ) internal onlyAavegotchiOwner(gotchiId) onlyAavegotchiUnlocked(gotchiId) {
+ function _forge(uint256 itemId, uint256 gotchiId, uint40 _gltr) internal onlyAavegotchiOwner(gotchiId) onlyAavegotchiUnlocked(gotchiId) {
require(!s.gotchiForging[gotchiId].isForging, "ForgeFacet: Aavegotchi already forging");
address sender = LibMeta.msgSender();
@@ -403,7 +399,7 @@ contract ForgeFacet is Modifiers {
uint40 blockLeft = queueItem.readyBlock - uint40(block.number);
uint40 removeBlocks = _amounts[i] <= blockLeft ? _amounts[i] : blockLeft;
- uint256 burnAmount = uint256(removeBlocks) * 10**18;
+ uint256 burnAmount = uint256(removeBlocks) * 10 ** 18;
require(
gltrContract().transferFrom(msg.sender, 0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF, burnAmount),
@@ -451,11 +447,7 @@ contract ForgeFacet is Modifiers {
}
}
- function forgeWearables(
- uint256[] calldata _itemIds,
- uint256[] calldata _gotchiIds,
- uint40[] calldata _gltr
- ) external whenNotPaused {
+ function forgeWearables(uint256[] calldata _itemIds, uint256[] calldata _gotchiIds, uint40[] calldata _gltr) external whenNotPaused {
require(_itemIds.length == _gotchiIds.length && _gotchiIds.length == _gltr.length, "ForgeFacet: mismatched array lengths");
for (uint256 i; i < _itemIds.length; i++) {
@@ -475,10 +467,8 @@ contract ForgeFacet is Modifiers {
// @notice Allow Aavegotchi diamond to mint essence.
// @dev Only called from CollateralFacet's decreaseAndDestroy function. Not including a whenNotPaused modifier
// here to avoid impacts to aavegotchi sacrifice functionality.
- function mintEssence(
- address owner /*uint256 gotchiId*/
- ) external {
- require(LibMeta.msgSender() == ForgeLibDiamond.AAVEGOTCHI_DIAMOND, "ForgeFacet: Can only be called by Aavegotchi Diamond");
+ function mintEssence(address owner /*uint256 gotchiId*/) external {
+ require(LibMeta.msgSender() == ForgeLibDiamond.AAVEGOTCHI_DIAMOND(), "ForgeFacet: Can only be called by Aavegotchi Diamond");
// require(aavegotchiFacet.ownerOf(gotchiId) == address(0), "ForgeFacet: Aavegotchi not sacrificed");
_mintItem(owner, ESSENCE, 1000);
@@ -522,41 +512,25 @@ contract ForgeFacet is Modifiers {
}
}
- function _mintItem(
- address account,
- uint256 id,
- uint256 amount
- ) internal {
+ function _mintItem(address account, uint256 id, uint256 amount) internal {
// mint doesnt exceed max supply
// require(totalSupply(id) + amount <= s.maxSupplyByToken[id], "ForgeFacet: mint would exceed max supply");
_mint(account, id, amount);
}
- function adminMint(
- address account,
- uint256 id,
- uint256 amount
- ) external onlyDaoOrOwner {
+ function adminMint(address account, uint256 id, uint256 amount) external onlyDaoOrOwner {
// mint doesnt exceed max supply
// require(totalSupply(id) + amount <= s.maxSupplyByToken[id], "ForgeFacet: mint would exceed max supply");
_mint(account, id, amount);
}
- function adminMintBatch(
- address to,
- uint256[] memory ids,
- uint256[] memory amounts
- ) external onlyDaoOrOwner {
+ function adminMintBatch(address to, uint256[] memory ids, uint256[] memory amounts) external onlyDaoOrOwner {
// mint doesnt exceed max supply
// require(totalSupply(id) + amount <= s.maxSupplyByToken[id], "ForgeFacet: mint would exceed max supply");
_mintBatch(to, ids, amounts);
}
- function burn(
- address account,
- uint256 id,
- uint256 amount
- ) external {
+ function burn(address account, uint256 id, uint256 amount) external {
require(
account == msg.sender || forgeTokenFacet().isApprovedForAll(account, msg.sender),
"ForgeFacet: caller is not token owner or approved"
@@ -568,11 +542,7 @@ contract ForgeFacet is Modifiers {
// function _mintBatchItems(address to, uint256[] memory ids, uint256[] memory amounts) internal {
// _mintBatch(to, ids, amounts, "");
// }
- function _burnItem(
- address account,
- uint256 id,
- uint256 amount
- ) internal {
+ function _burnItem(address account, uint256 id, uint256 amount) internal {
_burn(account, id, amount);
}
@@ -604,11 +574,7 @@ contract ForgeFacet is Modifiers {
emit TransferBatch(msg.sender, address(0), to, ids, amounts);
}
- function _burn(
- address from,
- uint256 id,
- uint256 amount
- ) internal virtual {
+ function _burn(address from, uint256 id, uint256 amount) internal virtual {
require(from != address(0), "ForgeTokenFacet: burn from the zero address");
uint256 fromBalance = s._balances[id][from];
@@ -621,11 +587,7 @@ contract ForgeFacet is Modifiers {
emit TransferSingle(msg.sender, from, address(0), id, amount);
}
- function _burnBatch(
- address from,
- uint256[] memory ids,
- uint256[] memory amounts
- ) internal virtual {
+ function _burnBatch(address from, uint256[] memory ids, uint256[] memory amounts) internal virtual {
require(from != address(0), "ForgeTokenFacet: burn from the zero address");
require(ids.length == amounts.length, "ForgeTokenFacet: ids and amounts length mismatch");
diff --git a/contracts/Aavegotchi/ForgeDiamond/facets/ForgeVRFFacet.sol b/contracts/Aavegotchi/ForgeDiamond/facets/ForgeVRFFacet.sol
index 3cf1c8a68..8ac490d8e 100644
--- a/contracts/Aavegotchi/ForgeDiamond/facets/ForgeVRFFacet.sol
+++ b/contracts/Aavegotchi/ForgeDiamond/facets/ForgeVRFFacet.sol
@@ -8,8 +8,6 @@ import {ILink} from "../../interfaces/ILink.sol";
import {ForgeFacet} from "./ForgeFacet.sol";
import {ForgeTokenFacet} from "./ForgeTokenFacet.sol";
-
-
contract ForgeVRFFacet is Modifiers {
event VrfResponse(address user, uint256 randomNumber, bytes32 requestId, uint256 blockNumber);
event GeodeWin(address user, uint256 itemId, uint256 geodeTokenId, bytes32 requestId, uint256 blockNumber);
@@ -116,7 +114,7 @@ contract ForgeVRFFacet is Modifiers {
s.vrfUserToRequestIds[sender].push(requestId);
// for testing
- // tempFulfillRandomness(requestId, uint256(keccak256(abi.encodePacked(block.number, _geodeTokenIds[0]))));
+ // tempFulfillRandomness(requestId, uint256(keccak256(abi.encodePacked(block.number, _geodeTokenIds[0]))));
}
// for testing purpose only
@@ -325,13 +323,11 @@ contract ForgeVRFFacet is Modifiers {
if (data.rarityWonIndex >= 0) {
data.prizes = getAvailablePrizesForRarity(rarities[uint(data.rarityWonIndex)]);
-
-
uint256 idx = data.geodeRandNum % data.prizes.length;
data.itemIdWon = data.prizes[idx];
-
+
// if last quantity of item won, rearrange array.
if (s.geodePrizeQuantities[data.itemIdWon] == 1) {
// find index in geodePrizeTokenIds
@@ -342,14 +338,11 @@ contract ForgeVRFFacet is Modifiers {
break;
}
}
-
s.geodePrizeTokenIds[tokenIdsIndex] = s.geodePrizeTokenIds[s.geodePrizeTokenIds.length - 1];
s.geodePrizeTokenIds.pop();
}
-
-
s.geodePrizeQuantities[data.itemIdWon] -= 1;
data.numWins++;
@@ -358,8 +351,6 @@ contract ForgeVRFFacet is Modifiers {
emit GeodeWin(sender, data.itemIdWon, info.geodeTokenIds[i], requestId, block.number);
} else {
-
-
forgeFacet().burn(address(this), info.geodeTokenIds[i], 1);
emit GeodeEmpty(sender, info.geodeTokenIds[i], requestId, block.number);
}
diff --git a/contracts/Aavegotchi/ForgeDiamond/libraries/ForgeLibDiamond.sol b/contracts/Aavegotchi/ForgeDiamond/libraries/ForgeLibDiamond.sol
index cc45bb049..aec0068f9 100644
--- a/contracts/Aavegotchi/ForgeDiamond/libraries/ForgeLibDiamond.sol
+++ b/contracts/Aavegotchi/ForgeDiamond/libraries/ForgeLibDiamond.sol
@@ -37,12 +37,14 @@ library ForgeLibDiamond {
// owner of the contract
address contractOwner;
//aavegotchi master diamond address
- address aavegotchiDiamond;
+ address AAVEGOTCHI_DIAMOND;
+ //aavegotchi wearable diamond address
+ address WEARABLE_DIAMOND;
}
bytes32 public constant DIAMOND_STORAGE_POSITION = keccak256("diamond.standard.diamond.storage");
- address public constant AAVEGOTCHI_DIAMOND = 0x86935F11C86623deC8a25696E1C19a8659CbF95d;
- address public constant WEARABLE_DIAMOND = 0x58de9AaBCaeEC0f69883C94318810ad79Cc6a44f;
+ // address public constant AAVEGOTCHI_DIAMOND = 0x86935F11C86623deC8a25696E1C19a8659CbF95d;
+ // address public constant WEARABLE_DIAMOND = 0x58de9AaBCaeEC0f69883C94318810ad79Cc6a44f;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
@@ -60,6 +62,14 @@ library ForgeLibDiamond {
emit OwnershipTransferred(previousOwner, _newOwner);
}
+ function WEARABLE_DIAMOND() internal view returns (address wearableDiamond_) {
+ wearableDiamond_ = diamondStorage().WEARABLE_DIAMOND;
+ }
+
+ function AAVEGOTCHI_DIAMOND() internal view returns (address aavegotchiDiamond_) {
+ aavegotchiDiamond_ = diamondStorage().AAVEGOTCHI_DIAMOND;
+ }
+
function contractOwner() internal view returns (address contractOwner_) {
contractOwner_ = diamondStorage().contractOwner;
}
@@ -69,16 +79,12 @@ library ForgeLibDiamond {
}
function enforceIsDiamond() internal view {
- require(msg.sender == AAVEGOTCHI_DIAMOND, "LibDiamond: Caller must be Aavegotchi Diamond");
+ require(msg.sender == AAVEGOTCHI_DIAMOND(), "LibDiamond: Caller must be Aavegotchi Diamond");
}
event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);
- function addDiamondFunctions(
- address _diamondCutFacet,
- address _diamondLoupeFacet,
- address _ownershipFacet
- ) internal {
+ function addDiamondFunctions(address _diamondCutFacet, address _diamondLoupeFacet, address _ownershipFacet) internal {
IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](3);
bytes4[] memory functionSelectors = new bytes4[](1);
functionSelectors[0] = IDiamondCut.diamondCut.selector;
@@ -102,11 +108,7 @@ library ForgeLibDiamond {
}
// Internal function version of diamondCut
- function diamondCut(
- IDiamondCut.FacetCut[] memory _diamondCut,
- address _init,
- bytes memory _calldata
- ) internal {
+ function diamondCut(IDiamondCut.FacetCut[] memory _diamondCut, address _init, bytes memory _calldata) internal {
for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {
IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;
if (action == IDiamondCut.FacetCutAction.Add) {
diff --git a/contracts/Aavegotchi/ForgeDiamond/libraries/LibAppStorage.sol b/contracts/Aavegotchi/ForgeDiamond/libraries/LibAppStorage.sol
index 0e0e1c27b..15a4ee573 100644
--- a/contracts/Aavegotchi/ForgeDiamond/libraries/LibAppStorage.sol
+++ b/contracts/Aavegotchi/ForgeDiamond/libraries/LibAppStorage.sol
@@ -168,7 +168,6 @@ struct AppStorage {
mapping(uint8 => uint256) forgeTimeCostInBlocks;
// Map rarity score modifier (which denotes item rarity) to number of skill points earned for successful forging.
mapping(uint8 => uint256) skillPointsEarnedFromForge;
-
// Map rarity score modifier (which denotes item rarity) to percent chance (in bips) to win a prize.
/**** NOTE: Deprecated *****/
mapping(uint8 => uint256) geodeWinChanceBips;
@@ -190,7 +189,6 @@ struct AppStorage {
address vrfCoordinator;
bytes32 keyHash;
uint144 vrfFee;
-
mapping(uint8 => mapping(uint8 => uint256)) geodeWinChanceMultiTierBips;
mapping(uint256 => uint8) geodePrizeRarities;
}
diff --git a/contracts/Aavegotchi/InitDiamond.sol b/contracts/Aavegotchi/InitDiamond.sol
index 4e2cb2fb9..79a07281e 100644
--- a/contracts/Aavegotchi/InitDiamond.sol
+++ b/contracts/Aavegotchi/InitDiamond.sol
@@ -20,9 +20,8 @@ contract InitDiamond {
address rarityFarming;
address ghstContract;
bytes32 chainlinkKeyHash;
- uint256 chainlinkFee;
+ uint64 subscriptionId;
address vrfCoordinator;
- address linkAddress;
address childChainManager;
string name;
string symbol;
@@ -48,9 +47,8 @@ contract InitDiamond {
s.ghstContract = _args.ghstContract;
s.keyHash = _args.chainlinkKeyHash;
- s.fee = uint144(_args.chainlinkFee);
+ s.subscriptionId = (_args.subscriptionId);
s.vrfCoordinator = _args.vrfCoordinator;
- s.link = ILink(_args.linkAddress);
s.listingFeeInWei = 1e17;
diff --git a/contracts/Aavegotchi/WearableDiamond/WearableDiamond.sol b/contracts/Aavegotchi/WearableDiamond/WearableDiamond.sol
index 02529c5d4..7d9f99702 100644
--- a/contracts/Aavegotchi/WearableDiamond/WearableDiamond.sol
+++ b/contracts/Aavegotchi/WearableDiamond/WearableDiamond.sol
@@ -13,15 +13,11 @@ import {DiamondLoupeFacet} from "../../shared/facets/DiamondLoupeFacet.sol";
import {OwnershipFacet} from "../../shared/facets/OwnershipFacet.sol";
contract WearableDiamond {
- constructor(
- address _contractOwner,
- address _diamondCutFacet,
- address _diaomondLoupeFacet,
- address _ownershipFacet
- ) {
+ constructor(address _contractOwner, address _diamondCutFacet, address _diaomondLoupeFacet, address _ownershipFacet, address aavegotchiDiamond) {
WearableLibDiamond.setContractOwner(_contractOwner);
WearableLibDiamond.addDiamondFunctions(_diamondCutFacet, _diaomondLoupeFacet, _ownershipFacet);
WearableLibDiamond.DiamondStorage storage ds = WearableLibDiamond.diamondStorage();
+ ds.AAVEGOTCHI_DIAMOND = aavegotchiDiamond;
ds.supportedInterfaces[0xd9b67a26] = true; //erc1155
}
diff --git a/contracts/Aavegotchi/WearableDiamond/facets/WearablesFacet.sol b/contracts/Aavegotchi/WearableDiamond/facets/WearablesFacet.sol
index c4c73f350..fcd13f07a 100644
--- a/contracts/Aavegotchi/WearableDiamond/facets/WearablesFacet.sol
+++ b/contracts/Aavegotchi/WearableDiamond/facets/WearablesFacet.sol
@@ -9,16 +9,16 @@ import {ItemsFacet} from "../../facets/ItemsFacet.sol";
import {AavegotchiFacet} from "../../facets/AavegotchiFacet.sol";
contract WearablesFacet {
- function periphery() internal pure returns (PeripheryFacet pFacet) {
- pFacet = PeripheryFacet(WearableLibDiamond.AAVEGOTCHI_DIAMOND);
+ function periphery() internal view returns (PeripheryFacet pFacet) {
+ pFacet = PeripheryFacet(WearableLibDiamond.AAVEGOTCHI_DIAMOND());
}
- function itemsFacet() internal pure returns (ItemsFacet iFacet) {
- iFacet = ItemsFacet(WearableLibDiamond.AAVEGOTCHI_DIAMOND);
+ function itemsFacet() internal view returns (ItemsFacet iFacet) {
+ iFacet = ItemsFacet(WearableLibDiamond.AAVEGOTCHI_DIAMOND());
}
- function aavegotchiFacet() internal pure returns (AavegotchiFacet aFacet) {
- aFacet = AavegotchiFacet(WearableLibDiamond.AAVEGOTCHI_DIAMOND);
+ function aavegotchiFacet() internal view returns (AavegotchiFacet aFacet) {
+ aFacet = AavegotchiFacet(WearableLibDiamond.AAVEGOTCHI_DIAMOND());
}
//READ
@@ -39,7 +39,7 @@ contract WearablesFacet {
approved_ = aavegotchiFacet().isApprovedForAll(_owner, _operator);
}
- function tokenURI(uint256 _tokenId) external pure returns (string memory) {
+ function tokenURI(uint256 _tokenId) external view returns (string memory) {
return aavegotchiFacet().tokenURI(_tokenId);
}
@@ -65,25 +65,13 @@ contract WearablesFacet {
}
}
- function safeTransferFrom(
- address _from,
- address _to,
- uint256 _id,
- uint256 _value,
- bytes calldata _data
- ) external {
+ function safeTransferFrom(address _from, address _to, uint256 _id, uint256 _value, bytes calldata _data) external {
periphery().peripherySafeTransferFrom(msg.sender, _from, _to, _id, _value, _data);
//emit event
LibEventHandler._receiveAndEmitTransferSingleEvent(msg.sender, _from, _to, _id, _value);
}
- function safeBatchTransferFrom(
- address _from,
- address _to,
- uint256[] calldata _ids,
- uint256[] calldata _values,
- bytes calldata _data
- ) external {
+ function safeBatchTransferFrom(address _from, address _to, uint256[] calldata _ids, uint256[] calldata _values, bytes calldata _data) external {
periphery().peripherySafeBatchTransferFrom(msg.sender, _from, _to, _ids, _values, _data);
//emit event
LibEventHandler._receiveAndEmitTransferBatchEvent(msg.sender, _from, _to, _ids, _values);
diff --git a/contracts/Aavegotchi/WearableDiamond/libraries/WearableLibDiamond.sol b/contracts/Aavegotchi/WearableDiamond/libraries/WearableLibDiamond.sol
index ceb24320e..5f0ac9049 100644
--- a/contracts/Aavegotchi/WearableDiamond/libraries/WearableLibDiamond.sol
+++ b/contracts/Aavegotchi/WearableDiamond/libraries/WearableLibDiamond.sol
@@ -14,7 +14,7 @@ import {LibMeta} from "../../../shared/libraries/LibMeta.sol";
library WearableLibDiamond {
bytes32 constant DIAMOND_STORAGE_POSITION = keccak256("diamond.standard.diamond.storage");
- address constant AAVEGOTCHI_DIAMOND = 0x86935F11C86623deC8a25696E1C19a8659CbF95d;
+ // address constant AAVEGOTCHI_DIAMOND = 0x86935F11C86623deC8a25696E1C19a8659CbF95d;
struct FacetAddressAndPosition {
address facetAddress;
@@ -40,7 +40,7 @@ library WearableLibDiamond {
// owner of the contract
address contractOwner;
//aavegotchi master diamond address
- address aavegotchiDiamond;
+ address AAVEGOTCHI_DIAMOND;
}
function diamondStorage() internal pure returns (DiamondStorage storage ds) {
@@ -50,6 +50,10 @@ library WearableLibDiamond {
}
}
+ function AAVEGOTCHI_DIAMOND() internal view returns (address) {
+ return diamondStorage().AAVEGOTCHI_DIAMOND;
+ }
+
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
function setContractOwner(address _newOwner) internal {
@@ -68,16 +72,12 @@ library WearableLibDiamond {
}
function enforceIsDiamond() internal view {
- require(msg.sender == AAVEGOTCHI_DIAMOND, "LibDiamond: Caller must be Aavegotchi Diamond");
+ require(msg.sender == diamondStorage().AAVEGOTCHI_DIAMOND, "LibDiamond: Caller must be Aavegotchi Diamond");
}
event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);
- function addDiamondFunctions(
- address _diamondCutFacet,
- address _diamondLoupeFacet,
- address _ownershipFacet
- ) internal {
+ function addDiamondFunctions(address _diamondCutFacet, address _diamondLoupeFacet, address _ownershipFacet) internal {
IDiamondCut.FacetCut[] memory cut = new IDiamondCut.FacetCut[](3);
bytes4[] memory functionSelectors = new bytes4[](1);
functionSelectors[0] = IDiamondCut.diamondCut.selector;
@@ -101,11 +101,7 @@ library WearableLibDiamond {
}
// Internal function version of diamondCut
- function diamondCut(
- IDiamondCut.FacetCut[] memory _diamondCut,
- address _init,
- bytes memory _calldata
- ) internal {
+ function diamondCut(IDiamondCut.FacetCut[] memory _diamondCut, address _init, bytes memory _calldata) internal {
for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {
IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;
if (action == IDiamondCut.FacetCutAction.Add) {
diff --git a/contracts/Aavegotchi/facets/AavegotchiGameFacet.sol b/contracts/Aavegotchi/facets/AavegotchiGameFacet.sol
index a2d6a3c26..ba0fbf10f 100644
--- a/contracts/Aavegotchi/facets/AavegotchiGameFacet.sol
+++ b/contracts/Aavegotchi/facets/AavegotchiGameFacet.sol
@@ -230,7 +230,11 @@ contract AavegotchiGameFacet is Modifiers {
///@param _tokenId The identifier of NFT to claim an Aavegotchi from
///@param _option The index of the aavegotchi to claim(1-10)
///@param _stakeAmount Minimum amount of collateral tokens needed to be sent to the new aavegotchi escrow contract
- function claimAavegotchi(uint256 _tokenId, uint256 _option, uint256 _stakeAmount) external onlyUnlocked(_tokenId) onlyAavegotchiOwner(_tokenId) {
+ function claimAavegotchi(
+ uint256 _tokenId,
+ uint256 _option,
+ uint256 _stakeAmount
+ ) external onlyUnlocked(_tokenId) onlyAavegotchiOwner(_tokenId) {
Aavegotchi storage aavegotchi = s.aavegotchis[_tokenId];
require(aavegotchi.status == LibAavegotchi.STATUS_OPEN_PORTAL, "AavegotchiGameFacet: Portal not open");
require(_option < PORTAL_AAVEGOTCHIS_NUM, "AavegotchiGameFacet: Only 10 aavegotchi options available");
diff --git a/contracts/Aavegotchi/facets/DAOFacet.sol b/contracts/Aavegotchi/facets/DAOFacet.sol
index 776670494..e83c4aa5a 100644
--- a/contracts/Aavegotchi/facets/DAOFacet.sol
+++ b/contracts/Aavegotchi/facets/DAOFacet.sol
@@ -31,6 +31,8 @@ contract DAOFacet is Modifiers {
event ItemModifiersSet(uint256 _wearableId, int8[6] _traitModifiers, uint8 _rarityScoreModifier);
event RemoveExperience(uint256[] _tokenIds, uint256[] _xpValues);
event UpdateItemPrice(uint256 _itemId, uint256 _priceInWei);
+ event GotchiGeistBridgeUpdate(address _newBridge);
+ event ItemGeistBridgeUpdate(address _newBridge);
/***********************************|
| Read Functions |
@@ -99,7 +101,11 @@ contract DAOFacet is Modifiers {
//First handle global collateralTypes array
uint256 index = s.collateralTypeIndexes[newCollateralType];
- bool collateralExists = index > 0 || s.collateralTypes[0] == newCollateralType;
+ bool collateralExists = index > 0;
+
+ if (!collateralExists && s.collateralTypes.length == 1 && s.collateralTypes[0] == newCollateralType) {
+ collateralExists = true;
+ }
if (!collateralExists) {
s.collateralTypes.push(newCollateralType);
@@ -174,7 +180,11 @@ contract DAOFacet is Modifiers {
///@param _hauntMaxSize The maximum number of portals in the new haunt
///@param _portalPrice The base price of portals in the new haunt(in $GHST)
///@param _bodyColor The universal body color applied to NFTs in the new haunt
- function createHaunt(uint24 _hauntMaxSize, uint96 _portalPrice, bytes3 _bodyColor) external onlyDaoOrOwner returns (uint256 hauntId_) {
+ function createHaunt(
+ uint24 _hauntMaxSize,
+ uint96 _portalPrice,
+ bytes3 _bodyColor
+ ) external onlyDaoOrOwner returns (uint256 hauntId_) {
uint256 currentHauntId = s.currentHauntId;
require(
s.haunts[currentHauntId].totalCount == s.haunts[currentHauntId].hauntMaxSize,
@@ -425,4 +435,18 @@ contract DAOFacet is Modifiers {
emit UpdateItemPrice(itemId, _newPrices[i]);
}
}
+
+ ///@notice Allow the DAO to update an address as a Geist bridge of the gotchi
+ ///@param _newBridge The address to be update as a bridge
+ function updateGotchiGeistBridge(address _newBridge) external onlyDaoOrOwner {
+ s.gotchGeistBridge = _newBridge;
+ emit GotchiGeistBridgeUpdate(_newBridge);
+ }
+
+ ///@notice Allow the DAO to update an address as a Geist bridge of the item
+ ///@param _newBridge The address to be update as a bridge
+ function updateItemGeistBridge(address _newBridge) external onlyDaoOrOwner {
+ s.itemGeistBridge = _newBridge;
+ emit ItemGeistBridgeUpdate(_newBridge);
+ }
}
diff --git a/contracts/Aavegotchi/facets/ItemsRolesRegistryFacet.sol b/contracts/Aavegotchi/facets/ItemsRolesRegistryFacet.sol
index df09d2539..942331250 100644
--- a/contracts/Aavegotchi/facets/ItemsRolesRegistryFacet.sol
+++ b/contracts/Aavegotchi/facets/ItemsRolesRegistryFacet.sol
@@ -17,7 +17,7 @@ import {LibERC1155} from "../../shared/libraries/LibERC1155.sol";
import {EnumerableSet} from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";
import {LibItemsEvents} from "../libraries/LibItemsEvents.sol";
-contract ItemsRolesRegistryFacet is Modifiers, IERC7589, ERC1155Holder {
+contract ItemsRolesRegistryFacet is Modifiers, IERC7589 {
using EnumerableSet for EnumerableSet.UintSet;
bytes32 public constant UNIQUE_ROLE = keccak256("Player()");
diff --git a/contracts/Aavegotchi/facets/PolygonXGeistBridgeFacet.sol b/contracts/Aavegotchi/facets/PolygonXGeistBridgeFacet.sol
new file mode 100644
index 000000000..c3f7b47bf
--- /dev/null
+++ b/contracts/Aavegotchi/facets/PolygonXGeistBridgeFacet.sol
@@ -0,0 +1,65 @@
+// SPDX-License-Identifier: MIT
+pragma solidity 0.8.1;
+
+import {Aavegotchi, Modifiers} from "../libraries/LibAppStorage.sol";
+import {LibAavegotchi} from "../libraries/LibAavegotchi.sol";
+import {LibItems} from "../libraries/LibItems.sol";
+import {LibERC721} from "../../shared/libraries/LibERC721.sol";
+import {LibERC1155} from "../../shared/libraries/LibERC1155.sol";
+import {INFTBridge} from "../../shared/interfaces/INFTBridge.sol";
+import {LibERC20} from "../../shared/libraries/LibERC20.sol";
+import {IERC20} from "../../shared/interfaces/IERC20.sol";
+import "../WearableDiamond/interfaces/IEventHandlerFacet.sol";
+
+contract PolygonXGeistBridgeFacet is Modifiers {
+
+ function bridgeGotchi(
+ address _receiver,
+ uint256 _tokenId,
+ uint256 _msgGasLimit,
+ address _connector
+ ) external payable {
+ Aavegotchi memory _aavegotchi = s.aavegotchis[_tokenId];
+ // force unstake from escrow
+ uint256 currentStake = IERC20(_aavegotchi.collateralType).balanceOf(_aavegotchi.escrow);
+ LibERC20.transferFrom(_aavegotchi.collateralType, _aavegotchi.escrow, msg.sender, currentStake);
+
+ bytes memory _metadata = abi.encode(_aavegotchi);
+ INFTBridge(s.gotchGeistBridge).bridge(_receiver, msg.sender, _tokenId, 1, _msgGasLimit, _connector, _metadata, new bytes(0));
+ for (uint slot; slot < _aavegotchi.equippedWearables.length; slot++) {
+ uint wearableId = _aavegotchi.equippedWearables[slot];
+ if (wearableId != 0) {
+ delete s.aavegotchis[_tokenId].equippedWearables[slot];
+ LibItems.removeFromParent(address(this), _tokenId, wearableId, 1);
+ LibItems.addToOwner(s.itemGeistBridge, wearableId, 1);
+ IEventHandlerFacet(s.wearableDiamond).emitTransferSingleEvent(msg.sender, address(this), s.itemGeistBridge, wearableId, 1);
+ emit LibERC1155.TransferFromParent(address(this), _tokenId, wearableId, 1);
+ }
+ }
+ }
+
+ function setMetadata(uint _tokenId, bytes memory _metadata) external onlyGotchiGeistBridge {
+ Aavegotchi memory _aavegotchi = abi.decode(_metadata, (Aavegotchi));
+ s.aavegotchis[_tokenId] = _aavegotchi;
+
+ for (uint slot; slot < _aavegotchi.equippedWearables.length; slot++) {
+ if (_aavegotchi.equippedWearables[slot] != 0) {
+ uint wearableId = _aavegotchi.equippedWearables[slot];
+ LibItems.removeFromOwner(s.itemGeistBridge, wearableId, 1);
+ IEventHandlerFacet(s.wearableDiamond).emitTransferSingleEvent(msg.sender, s.itemGeistBridge, address(this), wearableId, 1);
+ LibItems.addToParent(address(this), _tokenId, wearableId, 1);
+ emit LibERC1155.TransferToParent(address(this), _tokenId, wearableId, 1);
+ }
+ }
+ }
+
+ function bridgeItem(
+ address _receiver,
+ uint256 _tokenId,
+ uint256 _amount,
+ uint256 _msgGasLimit,
+ address _connector
+ ) external payable {
+ INFTBridge(s.itemGeistBridge).bridge(_receiver, msg.sender, _tokenId, _amount, _msgGasLimit, _connector, new bytes(0), new bytes(0));
+ }
+}
diff --git a/contracts/Aavegotchi/facets/VRFFacet.sol b/contracts/Aavegotchi/facets/VRFFacet.sol
index 08b93c645..c3f1223c1 100644
--- a/contracts/Aavegotchi/facets/VRFFacet.sol
+++ b/contracts/Aavegotchi/facets/VRFFacet.sol
@@ -6,6 +6,8 @@ import {LibMeta} from "../../shared/libraries/LibMeta.sol";
import {LibERC721Marketplace} from "../libraries/LibERC721Marketplace.sol";
import {LibAavegotchi} from "../libraries/LibAavegotchi.sol";
import {ILink} from "../interfaces/ILink.sol";
+import {VRFCoordinatorV2Interface} from "../interfaces/VRFCoordinatorV2Interface.sol";
+import {REQUEST_CONFIRMATIONS, NO_OF_WORDS, VRF_GAS_LIMIT} from "../libraries/LibAppStorage.sol";
//import "hardhat/console.sol";
@@ -92,17 +94,17 @@ contract VrfFacet is Modifiers {
| Read Functions |
|__________________________________*/
- function linkBalance() external view returns (uint256 linkBalance_) {
- linkBalance_ = s.link.balanceOf(address(this));
- }
+ // function linkBalance() external view returns (uint256 linkBalance_) {
+ // linkBalance_ = s.link.balanceOf(address(this));
+ // }
function vrfCoordinator() external view returns (address) {
return s.vrfCoordinator;
}
- function link() external view returns (address) {
- return address(s.link);
- }
+ // function link() external view returns (address) {
+ // return address(s.link);
+ // }
function keyHash() external view returns (bytes32) {
return s.keyHash;
@@ -131,22 +133,22 @@ contract VrfFacet is Modifiers {
emit OpenPortals(_tokenIds);
}
- function drawRandomNumber(uint256 _tokenId) internal {
+ function drawRandomNumber(uint256 _tokenId) internal returns (uint256 requestId_) {
s.aavegotchis[_tokenId].status = LibAavegotchi.STATUS_VRF_PENDING;
- uint256 fee = s.fee;
- require(s.link.balanceOf(address(this)) >= fee, "VrfFacet: Not enough LINK");
- bytes32 l_keyHash = s.keyHash;
- require(s.link.transferAndCall(s.vrfCoordinator, fee, abi.encode(l_keyHash, 0)), "VrfFacet: link transfer failed");
- uint256 vrfSeed = uint256(keccak256(abi.encode(l_keyHash, 0, address(this), s.vrfNonces[l_keyHash])));
- s.vrfNonces[l_keyHash]++;
- bytes32 requestId = keccak256(abi.encodePacked(l_keyHash, vrfSeed));
- s.vrfRequestIdToTokenId[requestId] = _tokenId;
+ requestId_ = VRFCoordinatorV2Interface(s.vrfCoordinator).requestRandomWords(
+ s.keyHash,
+ s.subscriptionId,
+ REQUEST_CONFIRMATIONS,
+ VRF_GAS_LIMIT,
+ NO_OF_WORDS
+ );
+ s.vrfRequestIdToTokenId[requestId_] = _tokenId;
// for testing
- tempFulfillRandomness(requestId, uint256(keccak256(abi.encodePacked(block.number, _tokenId))));
+ // tempFulfillRandomness(requestId_, uint256(keccak256(abi.encodePacked(block.number, _tokenId))));
}
// for testing purpose only
- function tempFulfillRandomness(bytes32 _requestId, uint256 _randomNumber) internal {
+ function tempFulfillRandomness(uint256 _requestId, uint256 _randomNumber) internal {
// console.log("bytes");
// console.logBytes32(_requestId);
//_requestId; // mentioned here to remove unused variable warning
@@ -174,19 +176,18 @@ contract VrfFacet is Modifiers {
* @dev rawFulfillRandomness, below.)
*
* @param _requestId The Id initially returned by requestRandomness
- * @param _randomNumber the VRF output
+ * @param _randomWords the VRF output
*/
- function rawFulfillRandomness(bytes32 _requestId, uint256 _randomNumber) external {
- uint256 tokenId = s.vrfRequestIdToTokenId[_requestId];
-
+ function rawFulfillRandomWords(uint256 _requestId, uint256[] memory _randomWords) external {
require(LibMeta.msgSender() == s.vrfCoordinator, "Only VRFCoordinator can fulfill");
-
+ uint256 tokenId = s.vrfRequestIdToTokenId[_requestId];
require(s.aavegotchis[tokenId].status == LibAavegotchi.STATUS_VRF_PENDING, "VrfFacet: VRF is not pending");
+
s.aavegotchis[tokenId].status = LibAavegotchi.STATUS_OPEN_PORTAL;
- s.tokenIdToRandomNumber[tokenId] = _randomNumber;
+ s.tokenIdToRandomNumber[tokenId] = _randomWords[0];
emit PortalOpened(tokenId);
- emit VrfRandomNumber(tokenId, _randomNumber, block.timestamp);
+ emit VrfRandomNumber(tokenId, _randomWords[0], block.timestamp);
}
///@notice Allow the aavegotchi diamond owner to change the vrf details
@@ -194,14 +195,9 @@ contract VrfFacet is Modifiers {
//@param _keyHash New keyhash
//@param _vrfCoordinator The new vrf coordinator address
//@param _link New LINK token contract address
- function changeVrf(
- uint256 _newFee,
- bytes32 _keyHash,
- address _vrfCoordinator,
- address _link
- ) external onlyOwner {
- if (_newFee != 0) {
- s.fee = uint96(_newFee);
+ function changeVrf(uint64 _newSubscriptionId, bytes32 _keyHash, address _vrfCoordinator) external onlyOwner {
+ if (_newSubscriptionId != 0) {
+ s.subscriptionId = _newSubscriptionId;
}
if (_keyHash != 0) {
s.keyHash = _keyHash;
@@ -209,13 +205,13 @@ contract VrfFacet is Modifiers {
if (_vrfCoordinator != address(0)) {
s.vrfCoordinator = _vrfCoordinator;
}
- if (_link != address(0)) {
- s.link = ILink(_link);
- }
}
- // Remove the LINK tokens from this contract that are used to pay for VRF random number fees
- function removeLinkTokens(address _to, uint256 _value) external onlyOwner {
- s.link.transfer(_to, _value);
+ function getVrfInfo() public view returns (uint64, bytes32, address, string memory) {
+ return (s.subscriptionId, s.keyHash, s.vrfCoordinator, s.name);
}
+ // // Remove the LINK tokens from this contract that are used to pay for VRF random number fees
+ // function removeLinkTokens(address _to, uint256 _value) external onlyOwner {
+ // s.link.transfer(_to, _value);
+ // }
}
diff --git a/contracts/Aavegotchi/interfaces/VRFCoordinatorV2Interface.sol b/contracts/Aavegotchi/interfaces/VRFCoordinatorV2Interface.sol
new file mode 100644
index 000000000..203f8e7bd
--- /dev/null
+++ b/contracts/Aavegotchi/interfaces/VRFCoordinatorV2Interface.sol
@@ -0,0 +1,113 @@
+// SPDX-License-Identifier: MIT
+pragma solidity 0.8.1;
+
+// solhint-disable-next-line interface-starts-with-i
+interface VRFCoordinatorV2Interface {
+ /**
+ * @notice Get configuration relevant for making requests
+ * @return minimumRequestConfirmations global min for request confirmations
+ * @return maxGasLimit global max for request gas limit
+ * @return s_provingKeyHashes list of registered key hashes
+ */
+ function getRequestConfig() external view returns (uint16, uint32, bytes32[] memory);
+
+ /**
+ * @notice Request a set of random words.
+ * @param keyHash - Corresponds to a particular oracle job which uses
+ * that key for generating the VRF proof. Different keyHash's have different gas price
+ * ceilings, so you can select a specific one to bound your maximum per request cost.
+ * @param subId - The ID of the VRF subscription. Must be funded
+ * with the minimum subscription balance required for the selected keyHash.
+ * @param minimumRequestConfirmations - How many blocks you'd like the
+ * oracle to wait before responding to the request. See SECURITY CONSIDERATIONS
+ * for why you may want to request more. The acceptable range is
+ * [minimumRequestBlockConfirmations, 200].
+ * @param callbackGasLimit - How much gas you'd like to receive in your
+ * fulfillRandomWords callback. Note that gasleft() inside fulfillRandomWords
+ * may be slightly less than this amount because of gas used calling the function
+ * (argument decoding etc.), so you may need to request slightly more than you expect
+ * to have inside fulfillRandomWords. The acceptable range is
+ * [0, maxGasLimit]
+ * @param numWords - The number of uint256 random values you'd like to receive
+ * in your fulfillRandomWords callback. Note these numbers are expanded in a
+ * secure way by the VRFCoordinator from a single random value supplied by the oracle.
+ * @return requestId - A unique identifier of the request. Can be used to match
+ * a request to a response in fulfillRandomWords.
+ */
+ function requestRandomWords(
+ bytes32 keyHash,
+ uint64 subId,
+ uint16 minimumRequestConfirmations,
+ uint32 callbackGasLimit,
+ uint32 numWords
+ ) external returns (uint256 requestId);
+
+ /**
+ * @notice Create a VRF subscription.
+ * @return subId - A unique subscription id.
+ * @dev You can manage the consumer set dynamically with addConsumer/removeConsumer.
+ * @dev Note to fund the subscription, use transferAndCall. For example
+ * @dev LINKTOKEN.transferAndCall(
+ * @dev address(COORDINATOR),
+ * @dev amount,
+ * @dev abi.encode(subId));
+ */
+ function createSubscription() external returns (uint64 subId);
+
+ /**
+ * @notice Get a VRF subscription.
+ * @param subId - ID of the subscription
+ * @return balance - LINK balance of the subscription in juels.
+ * @return reqCount - number of requests for this subscription, determines fee tier.
+ * @return owner - owner of the subscription.
+ * @return consumers - list of consumer address which are able to use this subscription.
+ */
+ function getSubscription(
+ uint64 subId
+ ) external view returns (uint96 balance, uint64 reqCount, address owner, address[] memory consumers);
+
+ /**
+ * @notice Request subscription owner transfer.
+ * @param subId - ID of the subscription
+ * @param newOwner - proposed new owner of the subscription
+ */
+ function requestSubscriptionOwnerTransfer(uint64 subId, address newOwner) external;
+
+ /**
+ * @notice Request subscription owner transfer.
+ * @param subId - ID of the subscription
+ * @dev will revert if original owner of subId has
+ * not requested that msg.sender become the new owner.
+ */
+ function acceptSubscriptionOwnerTransfer(uint64 subId) external;
+
+ /**
+ * @notice Add a consumer to a VRF subscription.
+ * @param subId - ID of the subscription
+ * @param consumer - New consumer which can use the subscription
+ */
+ function addConsumer(uint64 subId, address consumer) external;
+
+ /**
+ * @notice Remove a consumer from a VRF subscription.
+ * @param subId - ID of the subscription
+ * @param consumer - Consumer to remove from the subscription
+ */
+ function removeConsumer(uint64 subId, address consumer) external;
+
+ /**
+ * @notice Cancel a subscription
+ * @param subId - ID of the subscription
+ * @param to - Where to send the remaining LINK to
+ */
+ function cancelSubscription(uint64 subId, address to) external;
+
+ /*
+ * @notice Check to see if there exists a request commitment consumers
+ * for all consumers and keyhashes for a given sub.
+ * @param subId - ID of the subscription
+ * @return true if there exists at least one unfulfilled request for the subscription, false
+ * otherwise.
+ */
+ function pendingRequestExists(uint64 subId) external view returns (bool);
+}
\ No newline at end of file
diff --git a/contracts/Aavegotchi/libraries/LibAppStorage.sol b/contracts/Aavegotchi/libraries/LibAppStorage.sol
index c0928bd5a..acd38c8ce 100644
--- a/contracts/Aavegotchi/libraries/LibAppStorage.sol
+++ b/contracts/Aavegotchi/libraries/LibAppStorage.sol
@@ -2,7 +2,7 @@
pragma solidity 0.8.1;
import {LibDiamond} from "../../shared/libraries/LibDiamond.sol";
import {LibMeta} from "../../shared/libraries/LibMeta.sol";
-import {ILink} from "../interfaces/ILink.sol";
+
import {EnumerableSet} from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";
import {IERC7589} from "../../shared/interfaces/IERC7589.sol";
@@ -11,6 +11,10 @@ uint256 constant NUMERIC_TRAITS_NUM = 6;
uint256 constant TRAIT_BONUSES_NUM = 5;
uint256 constant PORTAL_AAVEGOTCHIS_NUM = 10;
+uint16 constant REQUEST_CONFIRMATIONS = 3;
+uint32 constant NO_OF_WORDS = 1;
+uint32 constant VRF_GAS_LIMIT = 2_500_000;
+
// switch (traitType) {
// case 0:
// return energy(value);
@@ -289,12 +293,11 @@ struct AppStorage {
string itemsBaseUri;
bytes32 domainSeparator;
//VRF
- mapping(bytes32 => uint256) vrfRequestIdToTokenId;
- mapping(bytes32 => uint256) vrfNonces;
+ mapping(uint256 => uint256) vrfRequestIdToTokenId;
+ // mapping(bytes32 => uint256) vrfNonces;
bytes32 keyHash;
- uint144 fee;
+ uint64 subscriptionId;
address vrfCoordinator;
- ILink link;
// Marketplace
uint256 nextERC1155ListingId;
// erc1155 category => erc1155Order
@@ -383,6 +386,8 @@ struct AppStorage {
// states for erc1155 buy orders
uint256 nextERC1155BuyOrderId;
mapping(uint256 => ERC1155BuyOrder) erc1155BuyOrders; // buyOrderId => data
+ address gotchGeistBridge;
+ address itemGeistBridge;
}
library LibAppStorage {
@@ -449,6 +454,18 @@ contract Modifiers {
_;
}
+ modifier onlyGotchiGeistBridge() {
+ address sender = LibMeta.msgSender();
+ require(sender == s.gotchGeistBridge, "LibAppStorage: Do not have access");
+ _;
+ }
+
+ modifier onlyItemGeistBridge() {
+ address sender = LibMeta.msgSender();
+ require(sender == s.itemGeistBridge, "LibAppStorage: Do not have access");
+ _;
+ }
+
modifier onlyPeriphery() {
address sender = LibMeta.msgSender();
require(sender == s.wearableDiamond, "LibAppStorage: Not wearable diamond");
diff --git a/contracts/shared/interfaces/INFTBridge.sol b/contracts/shared/interfaces/INFTBridge.sol
new file mode 100644
index 000000000..00411ed6c
--- /dev/null
+++ b/contracts/shared/interfaces/INFTBridge.sol
@@ -0,0 +1,22 @@
+// SPDX-License-Identifier: MIT
+pragma solidity 0.8.1;
+
+interface INFTBridge {
+ function bridge(
+ address receiver_,
+ address tokenOwner_,
+ uint256 tokenId_,
+ uint256 amount_,
+ uint256 msgGasLimit_,
+ address connector_,
+ bytes calldata extraData_,
+ bytes calldata options_
+ ) external payable;
+
+ function receiveInbound(
+ uint32 siblingChainSlug_,
+ bytes memory payload_
+ ) external payable;
+
+ function retry(address connector_, bytes32 messageId_) external;
+}
diff --git a/hardhat.config.ts b/hardhat.config.ts
index 3ba8ff5ea..9c7a2e525 100644
--- a/hardhat.config.ts
+++ b/hardhat.config.ts
@@ -38,7 +38,9 @@ require("./tasks/deployXPDrop");
// Go to https://buidler.dev/config/ to learn more
export default {
etherscan: {
- apiKey: process.env.POLYGON_API_KEY,
+ apiKey: {
+ matic: process.env.POLYGON_API_KEY,
+ },
},
networks: {
hardhat: {
@@ -72,7 +74,14 @@ export default {
gasPrice: 1000000000,
timeout: 90000,
},
-
+ amoy: {
+ url: process.env.AMOY_URL,
+ accounts: [process.env.SECRET],
+ },
+ "base-sepolia": {
+ url: process.env.BASE_SEPOLIA_URL,
+ accounts: [process.env.SECRET],
+ },
// gorli: {
// url: process.env.GORLI,
// accounts: [process.env.SECRET],
diff --git a/helpers/constants.ts b/helpers/constants.ts
index 8fabe3599..c3a14a171 100644
--- a/helpers/constants.ts
+++ b/helpers/constants.ts
@@ -66,6 +66,13 @@ export const CORE_PET_LEGENDARY = WEARABLE_GAP_OFFSET + 41;
export const CORE_PET_MYTHICAL = WEARABLE_GAP_OFFSET + 42;
export const CORE_PET_GODLIKE = WEARABLE_GAP_OFFSET + 43;
+export const AMOY_DIAMOND = "0xC80DB01aeDAD5F6E3088c75F60E52f579Cf1D3Cb";
+export const AMOY_DIAMOND_OWNER = "0xB9D736c48351Bad464710ee73BA80A0A659c1795";
+export const AMOY_GHST = "0xF679b8D109b2d23931237Ce948a7D784727c0897";
+export const AMOY_WEARABLE_DIAMOND =
+ "0xAA201d960404140296Ea85570940830be08DAc70";
+export const AMOY_FORGE_DIAMOND = "0xF7c2AC46723Ad844620F798ECe67f5C673120FB6";
+
export enum ERC1155_BAAZAAR_CATEGORY_TO_ID {
WEARABLE = 0,
BADGE = 1,
@@ -84,7 +91,6 @@ export enum ERC721_BAAZAAR_CATEGORY_TO_ID {
REALM = 4,
FAKEGOTCHIS = 5,
}
-
export enum WEARABLE_BASE_QUANTITIES {
COMMON = 1000,
UNCOMMON = 500,
diff --git a/js/diamond-util/src/index.js b/js/diamond-util/src/index.js
index 4bc2ba900..14eb4f0d4 100644
--- a/js/diamond-util/src/index.js
+++ b/js/diamond-util/src/index.js
@@ -1,101 +1,113 @@
/* global ethers */
+const { ethers } = require("hardhat");
+
const FacetCutAction = {
Add: 0,
Replace: 1,
- Remove: 2
-}
+ Remove: 2,
+};
// eslint-disable-next-line no-unused-vars
-function getSignatures (contract) {
- return Object.keys(contract.interface.functions)
+function getSignatures(contract) {
+ return Object.keys(contract.interface.functions);
}
-function getSelectors (contract) {
- const signatures = Object.keys(contract.interface.functions)
+function getSelectors(contract) {
+ const signatures = Object.keys(contract.interface.functions);
const selectors = signatures.reduce((acc, val) => {
- if (val !== 'init(bytes)') {
- acc.push(contract.interface.getSighash(val))
+ if (val !== "init(bytes)") {
+ acc.push(contract.interface.getSighash(val));
}
- return acc
- }, [])
- return selectors
+ return acc;
+ }, []);
+ return selectors;
}
-async function deployFacets (facets) {
- console.log('--')
- const deployed = []
+async function deployFacets(facets) {
+ console.log("--");
+ const deployed = [];
for (const facet of facets) {
if (Array.isArray(facet)) {
- if (typeof facet[0] !== 'string') {
- throw Error(`Error using facet: facet name must be a string. Bad input: ${facet[0]}`)
+ if (typeof facet[0] !== "string") {
+ throw Error(
+ `Error using facet: facet name must be a string. Bad input: ${facet[0]}`
+ );
}
if (!(facet[1] instanceof ethers.Contract)) {
- throw Error(`Error using facet: facet must be a Contract. Bad input: ${facet[1]}`)
+ throw Error(
+ `Error using facet: facet must be a Contract. Bad input: ${facet[1]}`
+ );
}
- console.log(`Using already deployed ${facet[0]}: ${facet[1].address}`)
- console.log('--')
- deployed.push(facet)
+ console.log(`Using already deployed ${facet[0]}: ${facet[1].address}`);
+ console.log("--");
+ deployed.push(facet);
} else {
- if (typeof facet !== 'string') {
- throw Error(`Error deploying facet: facet name must be a string. Bad input: ${facet}`)
+ if (typeof facet !== "string") {
+ throw Error(
+ `Error deploying facet: facet name must be a string. Bad input: ${facet}`
+ );
}
- const facetFactory = await ethers.getContractFactory(facet)
- console.log(`Deploying ${facet}`)
- const deployedFactory = await facetFactory.deploy()
- await deployedFactory.deployed()
- console.log(`${facet} deployed: ${deployedFactory.address}`)
- console.log('--')
- deployed.push([facet, deployedFactory])
+ const facetFactory = await ethers.getContractFactory(facet);
+ console.log(`Deploying ${facet}`);
+ const deployedFactory = await facetFactory.deploy();
+ await deployedFactory.deployed();
+ console.log(`${facet} deployed: ${deployedFactory.address}`);
+ console.log("--");
+ deployed.push([facet, deployedFactory]);
}
}
- return deployed
+ return deployed;
}
-async function deploy ({
+async function deploy({
diamondName,
initDiamond,
facets,
owner,
args = [],
- txArgs = {}
+ txArgs = {},
}) {
if (arguments.length !== 1) {
- throw Error(`Requires only 1 map argument. ${arguments.length} arguments used.`)
+ throw Error(
+ `Requires only 1 map argument. ${arguments.length} arguments used.`
+ );
}
- facets = await deployFacets(facets)
- const diamondFactory = await ethers.getContractFactory('Diamond')
- const diamondCut = []
- console.log('--')
- console.log('Setting up diamondCut args')
- console.log('--')
+ facets = await deployFacets(facets);
+ const diamondFactory = await ethers.getContractFactory("Diamond");
+ const diamondCut = [];
+ console.log("--");
+ console.log("Setting up diamondCut args");
+ console.log("--");
for (const [name, deployedFacet] of facets) {
- console.log(name)
- console.log(getSignatures(deployedFacet))
- console.log('--')
+ console.log(name);
+ console.log(getSignatures(deployedFacet));
+ console.log("--");
diamondCut.push([
deployedFacet.address,
FacetCutAction.Add,
- getSelectors(deployedFacet)
- ])
+ getSelectors(deployedFacet),
+ ]);
}
- console.log('--')
-
- let result
- if (typeof initDiamond === 'string') {
- const initDiamondName = initDiamond
- console.log(`Deploying ${initDiamondName}`)
- initDiamond = await ethers.getContractFactory(initDiamond)
- initDiamond = await initDiamond.deploy()
- await initDiamond.deployed()
- result = await initDiamond.deployTransaction.wait()
+ console.log("--");
+
+ let result;
+ if (typeof initDiamond === "string") {
+ const initDiamondName = initDiamond;
+ console.log(`Deploying ${initDiamondName}`);
+ initDiamond = await ethers.getContractFactory(initDiamond);
+ initDiamond = await initDiamond.deploy();
+ await initDiamond.deployed();
+ result = await initDiamond.deployTransaction.wait();
if (!result.status) {
- throw (Error(`Deploying ${initDiamondName} TRANSACTION FAILED!!! -------------------------------------------`))
+ throw Error(
+ `Deploying ${initDiamondName} TRANSACTION FAILED!!! -------------------------------------------`
+ );
}
}
- console.log('Encoding diamondCut init function call')
- const functionCall = initDiamond.interface.encodeFunctionData('init', args)
+ console.log("Encoding diamondCut init function call");
+ const functionCall = initDiamond.interface.encodeFunctionData("init", args);
// let functionCall
// if (args.length > 0) {
// functionCall = initDiamond.interface.encodeFunctionData("init", ...args)
@@ -103,194 +115,321 @@ async function deploy ({
// functionCall = initDiamond.interface.encodeFunctionData()
// }
- console.log(`Deploying ${diamondName}`)
+ console.log(`Deploying ${diamondName}`);
- const deployedDiamond = await diamondFactory.deploy(owner)
- await deployedDiamond.deployed()
- result = await deployedDiamond.deployTransaction.wait()
+ const deployedDiamond = await diamondFactory.deploy(owner);
+ await deployedDiamond.deployed();
+ result = await deployedDiamond.deployTransaction.wait();
if (!result.status) {
- console.log('Deploying diamond TRANSACTION FAILED!!! -------------------------------------------')
- console.log('See block explorer app for details.')
- console.log('Transaction hash:' + deployedDiamond.deployTransaction.hash)
- throw (Error('failed to deploy diamond'))
+ console.log(
+ "Deploying diamond TRANSACTION FAILED!!! -------------------------------------------"
+ );
+ console.log("See block explorer app for details.");
+ console.log("Transaction hash:" + deployedDiamond.deployTransaction.hash);
+ throw Error("failed to deploy diamond");
}
- console.log('Diamond deploy transaction hash:' + deployedDiamond.deployTransaction.hash)
+ console.log(
+ "Diamond deploy transaction hash:" + deployedDiamond.deployTransaction.hash
+ );
- console.log(`${diamondName} deployed: ${deployedDiamond.address}`)
- console.log(`Diamond owner: ${owner}`)
+ console.log(`${diamondName} deployed: ${deployedDiamond.address}`);
+ console.log(`Diamond owner: ${owner}`);
- const diamondCutFacet = await ethers.getContractAt('DiamondCutFacet', deployedDiamond.address)
- const tx = await diamondCutFacet.diamondCut(diamondCut, initDiamond.address, functionCall, txArgs)
+ const diamondCutFacet = await ethers.getContractAt(
+ "DiamondCutFacet",
+ deployedDiamond.address
+ );
+ const tx = await diamondCutFacet.diamondCut(
+ diamondCut,
+ initDiamond.address,
+ functionCall,
+ txArgs
+ );
// console.log(`${diamondName} diamondCut arguments:`)
// console.log(JSON.stringify([facets, initDiamond.address, args], null, 4))
- result = await tx.wait()
+ result = await tx.wait();
+ if (!result.status) {
+ console.log(
+ "TRANSACTION FAILED!!! -------------------------------------------"
+ );
+ console.log("See block explorer app for details.");
+ }
+ console.log("DiamondCut success!");
+ console.log("Transaction hash:" + tx.hash);
+ console.log("--");
+ return deployedDiamond;
+}
+
+async function deployWithoutInit({
+ diamondName,
+ facets,
+ args = [],
+ txArgs = {},
+}) {
+ if (arguments.length !== 1) {
+ throw Error(
+ `Requires only 1 map argument. ${arguments.length} arguments used.`
+ );
+ }
+ facets = await deployFacets(facets);
+ const diamondFactory = await ethers.getContractFactory(diamondName);
+ const diamondCut = [];
+ console.log("--");
+ console.log("Setting up diamondCut args");
+ console.log("--");
+ for (const [name, deployedFacet] of facets) {
+ console.log(name);
+ console.log(getSignatures(deployedFacet));
+ console.log("--");
+ diamondCut.push([
+ deployedFacet.address,
+ FacetCutAction.Add,
+ getSelectors(deployedFacet),
+ ]);
+ }
+ console.log("--");
+
+ let result;
+
+ console.log(`Deploying ${diamondName}`);
+ console.log(...args);
+ const deployedDiamond = await diamondFactory.deploy(...args);
+ console.log("here1");
+ await deployedDiamond.deployed();
+ console.log("here2");
+ result = await deployedDiamond.deployTransaction.wait();
+ if (!result.status) {
+ console.log(
+ "Deploying diamond TRANSACTION FAILED!!! -------------------------------------------"
+ );
+ console.log("See block explorer app for details.");
+ console.log("Transaction hash:" + deployedDiamond.deployTransaction.hash);
+ throw Error("failed to deploy diamond");
+ }
+ console.log(
+ "Diamond deploy transaction hash:" + deployedDiamond.deployTransaction.hash
+ );
+
+ console.log(`${diamondName} deployed: ${deployedDiamond.address}`);
+
+ const diamondCutFacet = await ethers.getContractAt(
+ "DiamondCutFacet",
+ deployedDiamond.address
+ );
+ const tx = await diamondCutFacet.diamondCut(
+ diamondCut,
+ ethers.constants.AddressZero,
+ "0x",
+ txArgs
+ );
+
+ result = await tx.wait();
if (!result.status) {
- console.log('TRANSACTION FAILED!!! -------------------------------------------')
- console.log('See block explorer app for details.')
+ console.log(
+ "TRANSACTION FAILED!!! -------------------------------------------"
+ );
+ console.log("See block explorer app for details.");
}
- console.log('DiamondCut success!')
- console.log('Transaction hash:' + tx.hash)
- console.log('--')
- return deployedDiamond
+ console.log("DiamondCut success!");
+ console.log("Transaction hash:" + tx.hash);
+ console.log("--");
+ return deployedDiamond;
}
-function inFacets (selector, facets) {
+function inFacets(selector, facets) {
for (const facet of facets) {
if (facet.functionSelectors.includes(selector)) {
- return true
+ return true;
}
}
- return false
+ return false;
}
-async function upgrade ({
+async function upgrade({
diamondAddress,
diamondCut,
txArgs = {},
initFacetName = undefined,
- initArgs
+ initArgs,
}) {
if (arguments.length !== 1) {
- throw Error(`Requires only 1 map argument. ${arguments.length} arguments used.`)
+ throw Error(
+ `Requires only 1 map argument. ${arguments.length} arguments used.`
+ );
}
- const diamondCutFacet = await ethers.getContractAt('DiamondCutFacet', diamondAddress)
- const diamondLoupeFacet = await ethers.getContractAt('DiamondLoupeFacet', diamondAddress)
- const existingFacets = await diamondLoupeFacet.facets()
- const facetFactories = new Map()
+ const diamondCutFacet = await ethers.getContractAt(
+ "DiamondCutFacet",
+ diamondAddress
+ );
+ const diamondLoupeFacet = await ethers.getContractAt(
+ "DiamondLoupeFacet",
+ diamondAddress
+ );
+ const existingFacets = await diamondLoupeFacet.facets();
+ const facetFactories = new Map();
- console.log('Facet Signatures and Selectors: ')
+ console.log("Facet Signatures and Selectors: ");
for (const facet of diamondCut) {
- const functions = new Map()
- const selectors = []
- console.log('Facet: ' + facet)
- let facetName
- let contract
+ const functions = new Map();
+ const selectors = [];
+ console.log("Facet: " + facet);
+ let facetName;
+ let contract;
if (Array.isArray(facet[0])) {
- facetName = facet[0][0]
- contract = facet[0][1]
- if (!(typeof facetName === 'string')) {
- throw Error('First value in facet[0] array must be a string.')
+ facetName = facet[0][0];
+ contract = facet[0][1];
+ if (!(typeof facetName === "string")) {
+ throw Error("First value in facet[0] array must be a string.");
}
if (!(contract instanceof ethers.Contract)) {
- throw Error('Second value in facet[0] array must be a Contract object.')
+ throw Error(
+ "Second value in facet[0] array must be a Contract object."
+ );
}
- facet[0] = facetName
+ facet[0] = facetName;
} else {
- facetName = facet[0]
- if (!(typeof facetName === 'string') && facetName) {
- throw Error('facet[0] must be a string or an array or false.')
+ facetName = facet[0];
+ if (!(typeof facetName === "string") && facetName) {
+ throw Error("facet[0] must be a string or an array or false.");
}
}
for (const signature of facet[2]) {
- const selector = ethers.utils.keccak256(ethers.utils.toUtf8Bytes(signature)).slice(0, 10)
- console.log(`Function: ${selector} ${signature}`)
- selectors.push(selector)
- functions.set(selector, signature)
+ const selector = ethers.utils
+ .keccak256(ethers.utils.toUtf8Bytes(signature))
+ .slice(0, 10);
+ console.log(`Function: ${selector} ${signature}`);
+ selectors.push(selector);
+ functions.set(selector, signature);
}
- console.log('')
+ console.log("");
if (facet[1] === FacetCutAction.Remove) {
if (facetName) {
- throw (Error(`Can't remove functions because facet name must have a false value not ${facetName}.`))
+ throw Error(
+ `Can't remove functions because facet name must have a false value not ${facetName}.`
+ );
}
- facet[0] = ethers.constants.AddressZero
+ facet[0] = ethers.constants.AddressZero;
for (const selector of selectors) {
if (!inFacets(selector, existingFacets)) {
- const signature = functions.get(selector)
- throw Error(`Can't remove '${signature}'. It doesn't exist in deployed diamond.`)
+ const signature = functions.get(selector);
+ throw Error(
+ `Can't remove '${signature}'. It doesn't exist in deployed diamond.`
+ );
}
}
- facet[2] = selectors
+ facet[2] = selectors;
} else if (facet[1] === FacetCutAction.Replace) {
- let facetFactory = facetFactories.get(facetName)
+ let facetFactory = facetFactories.get(facetName);
if (!facetFactory) {
if (contract) {
- facetFactories.set(facetName, contract)
+ facetFactories.set(facetName, contract);
} else {
- facetFactory = await ethers.getContractFactory(facetName)
- facetFactories.set(facetName, facetFactory)
+ facetFactory = await ethers.getContractFactory(facetName);
+ facetFactories.set(facetName, facetFactory);
}
}
for (const signature of facet[2]) {
- if (!Object.prototype.hasOwnProperty.call(facetFactory.interface.functions, signature)) {
- throw (Error(`Can't replace '${signature}'. It doesn't exist in ${facetName} source code.`))
+ if (
+ !Object.prototype.hasOwnProperty.call(
+ facetFactory.interface.functions,
+ signature
+ )
+ ) {
+ throw Error(
+ `Can't replace '${signature}'. It doesn't exist in ${facetName} source code.`
+ );
}
}
for (const selector of selectors) {
if (!inFacets(selector, existingFacets)) {
- const signature = functions.get(selector)
- throw Error(`Can't replace '${signature}'. It doesn't exist in deployed diamond.`)
+ const signature = functions.get(selector);
+ throw Error(
+ `Can't replace '${signature}'. It doesn't exist in deployed diamond.`
+ );
}
}
- facet[2] = selectors
+ facet[2] = selectors;
} else if (facet[1] === FacetCutAction.Add) {
- let facetFactory = facetFactories.get(facetName)
+ let facetFactory = facetFactories.get(facetName);
if (!facetFactory) {
if (contract) {
- facetFactories.set(facetName, contract)
+ facetFactories.set(facetName, contract);
} else {
- facetFactory = await ethers.getContractFactory(facetName)
- facetFactories.set(facetName, facetFactory)
+ facetFactory = await ethers.getContractFactory(facetName);
+ facetFactories.set(facetName, facetFactory);
}
}
for (const signature of facet[2]) {
- if (!Object.prototype.hasOwnProperty.call(facetFactory.interface.functions, signature)) {
- throw (Error(`Can't add ${signature}. It doesn't exist in ${facetName} source code.`))
+ if (
+ !Object.prototype.hasOwnProperty.call(
+ facetFactory.interface.functions,
+ signature
+ )
+ ) {
+ throw Error(
+ `Can't add ${signature}. It doesn't exist in ${facetName} source code.`
+ );
}
}
for (const selector of selectors) {
if (inFacets(selector, existingFacets)) {
- const signature = functions.get(selector)
- throw Error(`Can't add '${signature}'. It already exists in deployed diamond.`)
+ const signature = functions.get(selector);
+ throw Error(
+ `Can't add '${signature}'. It already exists in deployed diamond.`
+ );
}
}
- facet[2] = selectors
+ facet[2] = selectors;
} else {
- throw (Error('Incorrect FacetCutAction value. Must be 0, 1 or 2. Value used: ' + facet[1]))
+ throw Error(
+ "Incorrect FacetCutAction value. Must be 0, 1 or 2. Value used: " +
+ facet[1]
+ );
}
}
// deploying new facets
- const alreadDeployed = new Map()
+ const alreadDeployed = new Map();
for (const facet of diamondCut) {
if (facet[1] !== FacetCutAction.Remove) {
- const existingAddress = alreadDeployed.get(facet[0])
+ const existingAddress = alreadDeployed.get(facet[0]);
if (existingAddress) {
- facet[0] = existingAddress
- continue
+ facet[0] = existingAddress;
+ continue;
}
- console.log(`Deploying ${facet[0]}`)
- const facetFactory = facetFactories.get(facet[0])
- let deployedFacet = facetFactory
+ console.log(`Deploying ${facet[0]}`);
+ const facetFactory = facetFactories.get(facet[0]);
+ let deployedFacet = facetFactory;
if (!(deployedFacet instanceof ethers.Contract)) {
- deployedFacet = await facetFactory.deploy()
- await deployedFacet.deployed()
+ deployedFacet = await facetFactory.deploy();
+ await deployedFacet.deployed();
}
- facetFactories.set(facet[0], deployedFacet)
- console.log(`${facet[0]} deployed: ${deployedFacet.address}`)
- alreadDeployed.set(facet[0], deployedFacet.address)
- facet[0] = deployedFacet.address
+ facetFactories.set(facet[0], deployedFacet);
+ console.log(`${facet[0]} deployed: ${deployedFacet.address}`);
+ alreadDeployed.set(facet[0], deployedFacet.address);
+ facet[0] = deployedFacet.address;
}
}
- console.log('diamondCut arg:')
- console.log(diamondCut)
+ console.log("diamondCut arg:");
+ console.log(diamondCut);
- let initFacetAddress = ethers.constants.AddressZero
- let functionCall = '0x'
+ let initFacetAddress = ethers.constants.AddressZero;
+ let functionCall = "0x";
if (initFacetName !== undefined) {
- let initFacet = facetFactories.get(initFacetName)
+ let initFacet = facetFactories.get(initFacetName);
if (!initFacet) {
- const InitFacet = await ethers.getContractFactory(initFacetName)
- initFacet = await InitFacet.deploy()
- await initFacet.deployed()
- console.log('Deployed init facet: ' + initFacet.address)
+ const InitFacet = await ethers.getContractFactory(initFacetName);
+ initFacet = await InitFacet.deploy();
+ await initFacet.deployed();
+ console.log("Deployed init facet: " + initFacet.address);
} else {
- console.log('Using init facet: ' + initFacet.address)
+ console.log("Using init facet: " + initFacet.address);
}
- functionCall = initFacet.interface.encodeFunctionData('init', initArgs)
- console.log('Function call: ')
- console.log(functionCall)
- initFacetAddress = initFacet.address
+ functionCall = initFacet.interface.encodeFunctionData("init", initArgs);
+ console.log("Function call: ");
+ console.log(functionCall);
+ initFacetAddress = initFacet.address;
}
const result = await diamondCutFacet.diamondCut(
@@ -298,126 +437,137 @@ async function upgrade ({
initFacetAddress,
functionCall,
txArgs
- )
- const receipt = await result.wait()
+ );
+ const receipt = await result.wait();
if (!receipt.status) {
- console.log('TRANSACTION FAILED!!! -------------------------------------------')
- console.log('See block explorer app for details.')
+ console.log(
+ "TRANSACTION FAILED!!! -------------------------------------------"
+ );
+ console.log("See block explorer app for details.");
}
- console.log('------')
- console.log('Upgrade transaction hash: ' + result.hash)
- return result
+ console.log("------");
+ console.log("Upgrade transaction hash: " + result.hash);
+ return result;
}
-async function upgradeWithNewFacets ({
+async function upgradeWithNewFacets({
diamondAddress,
facetNames,
selectorsToRemove = [],
initFacetName = undefined,
- initArgs = []
+ initArgs = [],
}) {
if (arguments.length === 1) {
- throw Error(`Requires only 1 map argument. ${arguments.length} arguments used.`)
+ throw Error(
+ `Requires only 1 map argument. ${arguments.length} arguments used.`
+ );
}
- const diamondCutFacet = await ethers.getContractAt('DiamondCutFacet', diamondAddress)
- const diamondLoupeFacet = await ethers.getContractAt('DiamondLoupeFacet', diamondAddress)
+ const diamondCutFacet = await ethers.getContractAt(
+ "DiamondCutFacet",
+ diamondAddress
+ );
+ const diamondLoupeFacet = await ethers.getContractAt(
+ "DiamondLoupeFacet",
+ diamondAddress
+ );
- const diamondCut = []
- const existingFacets = await diamondLoupeFacet.facets()
- const undeployed = []
- const deployed = []
+ const diamondCut = [];
+ const existingFacets = await diamondLoupeFacet.facets();
+ const undeployed = [];
+ const deployed = [];
for (const name of facetNames) {
- console.log(name)
- const facetFactory = await ethers.getContractFactory(name)
- undeployed.push([name, facetFactory])
+ console.log(name);
+ const facetFactory = await ethers.getContractFactory(name);
+ undeployed.push([name, facetFactory]);
}
if (selectorsToRemove.length > 0) {
// check if any selectorsToRemove are already gone
for (const selector of selectorsToRemove) {
if (!inFacets(selector, existingFacets)) {
- throw Error('Function selector to remove is already gone.')
+ throw Error("Function selector to remove is already gone.");
}
}
diamondCut.push([
ethers.constants.AddressZeo,
FacetCutAction.Remove,
- selectorsToRemove
- ])
+ selectorsToRemove,
+ ]);
}
for (const [name, facetFactory] of undeployed) {
- console.log(`Deploying ${name}`)
- deployed.push([name, await facetFactory.deploy()])
+ console.log(`Deploying ${name}`);
+ deployed.push([name, await facetFactory.deploy()]);
}
for (const [name, deployedFactory] of deployed) {
- await deployedFactory.deployed()
- console.log('--')
- console.log(`${name} deployed: ${deployedFactory.address}`)
- const add = []
- const replace = []
+ await deployedFactory.deployed();
+ console.log("--");
+ console.log(`${name} deployed: ${deployedFactory.address}`);
+ const add = [];
+ const replace = [];
for (const selector of getSelectors(deployedFactory)) {
if (!inFacets(selector, existingFacets)) {
- add.push(selector)
+ add.push(selector);
} else {
- replace.push(selector)
+ replace.push(selector);
}
}
if (add.length > 0) {
- diamondCut.push([deployedFactory.address, FacetCutAction.Add, add])
+ diamondCut.push([deployedFactory.address, FacetCutAction.Add, add]);
}
if (replace.length > 0) {
diamondCut.push([
deployedFactory.address,
FacetCutAction.Replace,
- replace
- ])
+ replace,
+ ]);
}
}
- console.log('diamondCut arg:')
- console.log(diamondCut)
- console.log('------')
+ console.log("diamondCut arg:");
+ console.log(diamondCut);
+ console.log("------");
- let initFacetAddress = ethers.constants.AddressZero
- let functionCall = '0x'
+ let initFacetAddress = ethers.constants.AddressZero;
+ let functionCall = "0x";
if (initFacetName !== undefined) {
- let initFacet
+ let initFacet;
for (const [name, deployedFactory] of deployed) {
if (name === initFacetName) {
- initFacet = deployedFactory
- break
+ initFacet = deployedFactory;
+ break;
}
}
if (!initFacet) {
- const InitFacet = await ethers.getContractFactory(initFacetName)
- initFacet = await InitFacet.deploy()
- await initFacet.deployed()
- console.log('Deployed init facet: ' + initFacet.address)
+ const InitFacet = await ethers.getContractFactory(initFacetName);
+ initFacet = await InitFacet.deploy();
+ await initFacet.deployed();
+ console.log("Deployed init facet: " + initFacet.address);
} else {
- console.log('Using init facet: ' + initFacet.address)
+ console.log("Using init facet: " + initFacet.address);
}
- functionCall = initFacet.interface.encodeFunctionData('init', initArgs)
- console.log('Function call: ')
- console.log(functionCall)
- initFacetAddress = initFacet.address
+ functionCall = initFacet.interface.encodeFunctionData("init", initArgs);
+ console.log("Function call: ");
+ console.log(functionCall);
+ initFacetAddress = initFacet.address;
}
const result = await diamondCutFacet.diamondCut(
diamondCut,
initFacetAddress,
functionCall
- )
- console.log('------')
- console.log('Upgrade transaction hash: ' + result.hash)
- return result
+ );
+ console.log("------");
+ console.log("Upgrade transaction hash: " + result.hash);
+ return result;
}
-exports.FacetCutAction = FacetCutAction
-exports.upgrade = upgrade
-exports.upgradeWithNewFacets = upgradeWithNewFacets
-exports.getSelectors = getSelectors
-exports.deployFacets = deployFacets
-exports.deploy = deploy
-exports.inFacets = inFacets
-exports.upgrade = upgrade
+exports.FacetCutAction = FacetCutAction;
+exports.upgrade = upgrade;
+exports.upgradeWithNewFacets = upgradeWithNewFacets;
+exports.getSelectors = getSelectors;
+exports.deployFacets = deployFacets;
+exports.deploy = deploy;
+exports.deployWithoutInit = deployWithoutInit;
+exports.inFacets = inFacets;
+exports.upgrade = upgrade;
diff --git a/scripts/batchMintPortals.js b/scripts/batchMintPortals.js
index 05bf70723..27e5fb3a4 100644
--- a/scripts/batchMintPortals.js
+++ b/scripts/batchMintPortals.js
@@ -7,7 +7,8 @@ async function batchMintPortals() {
console.log("account:", account);
let nonceManagedSigner;
- const itemManager = "0x8D46fd7160940d89dA026D59B2e819208E714E82";
+ const itemManager = "0xd38Df837a1EAd12ee16f8b8b7E5F58703f841668";
+ let diamondAddress = "0x87C969d083189927049f8fF3747703FB9f7a8AEd";
const gasPrice = 50000000000;
@@ -20,7 +21,7 @@ async function batchMintPortals() {
});
signer = await ethers.provider.getSigner(itemManager);
nonceManagedSigner = new NonceManager(signer);
- } else if (hre.network.name === "matic") {
+ } else if (hre.network.name === "base-sepolia") {
signer = accounts[0]; // new ethers.Wallet(process.env.ITEM_MANAGER);
} else {
throw Error("Incorrect network selected");
@@ -29,25 +30,37 @@ async function batchMintPortals() {
console.log("Deploying Account: " + itemManager + "\n---");
let totalGasUsed = ethers.BigNumber.from("0");
- let shopFacet;
- let diamondAddress = "0x86935F11C86623deC8a25696E1C19a8659CbF95d";
console.log(`Batch minting Portals to Item Manager: ${itemManager}`);
- shopFacet = await ethers.getContractAt(
+ const shopFacet = await ethers.getContractAt(
"ShopFacet",
diamondAddress,
nonceManagedSigner
);
-
- let numberPerMint = 50;
- const maxNumber = 50; //15000;
- //Mint 2000 ERC721s
-
+ const vrfFacet = await ethers.getContractAt(
+ "VrfFacet",
+ diamondAddress,
+ nonceManagedSigner
+ );
const gameFacet = await ethers.getContractAt(
+ "AavegotchiGameFacet",
+ diamondAddress,
+ nonceManagedSigner
+ );
+ const aavegotchiFacet = await ethers.getContractAt(
"contracts/Aavegotchi/facets/AavegotchiFacet.sol:AavegotchiFacet",
diamondAddress
);
+ const ghstFacet = await ethers.getContractAt(
+ "GHSTFacet",
+ "0xe97f36a00058aa7dfc4e85d23532c3f70453a7ae"
+ );
+ await ghstFacet.approve(diamondAddress, ethers.utils.parseEther("100000000000000000000000"));
+
+ let numberPerMint = 50;
+ const maxNumber = 500; //15000;
+ //Mint 2000 ERC721s
let remaining = maxNumber;
@@ -68,12 +81,32 @@ async function batchMintPortals() {
totalGasUsed = totalGasUsed.add(r.gasLimit);
promises.push(r);
console.log("Total minted:", totalMinted);
- const balance = await gameFacet.balanceOf(itemManager);
+ const balance = await aavegotchiFacet.balanceOf(itemManager);
console.log("Balance of Item Manager:", balance.toString());
}
await Promise.all(promises);
+ // open portals
+ const startId = 50
+ for (let i = 0; i < 5; i++) {
+ let r = await vrfFacet.openPortals(Array.from({ length: 20 }, (_, j) => j + startId + i * 20), {
+ gasPrice: gasPrice,
+ });
+ console.log(`open portal from ${startId + i * 20}: tx hash:`, r.hash);
+ }
+
+ // claim gotchis
+ for (let i = 100; i < 150; i++) {
+ const gotchis = await gameFacet.portalAavegotchiTraits(i)
+ const selectedGotchi = gotchis[0]
+ let r = await gameFacet.claimAavegotchi(i, 0, selectedGotchi.minimumStake, {
+ gasPrice: gasPrice,
+ });
+ console.log(`claimAavegotchi ${i}: tx hash:`, r.hash);
+ }
+
+
console.log("Used Gas:", totalGasUsed.toString());
}
diff --git a/scripts/deployFullDiamond.ts b/scripts/deployFullDiamond.ts
new file mode 100644
index 000000000..590e9e481
--- /dev/null
+++ b/scripts/deployFullDiamond.ts
@@ -0,0 +1,742 @@
+/* global ethers hre */
+
+import { ethers, network } from "hardhat";
+
+import {
+ getItemTypes,
+ ItemTypeInputNew,
+ SleeveObject,
+ toItemTypeInputNew,
+} from "./itemTypeHelpers";
+import { itemTypes as allItemTypes } from "../data/itemTypes/itemTypes";
+import { wearableSetArrays } from "./wearableSets";
+
+import { DAOFacet, ERC1155BuyOrderFacet, SvgFacet } from "../typechain";
+import { BigNumberish, BigNumber } from "@ethersproject/bignumber";
+import { uploadSvgs } from "./svgHelperFunctions";
+import { getWearables } from "../svgs/allWearables";
+import { closedPortals, openedPortals } from "../svgs/portals";
+
+import { setForgeProperties } from "./upgrades/forge/upgrade-forgeSetters";
+import { aavegotchiSvgs as aavegotchiSideSvgs } from "../svgs/aavegotchi-side-typeScript";
+
+import {
+ eyeShapesLeftSvgs,
+ eyeShapesRightSvgs,
+} from "../svgs/eyeShapes-sidesOpt";
+import {
+ wearablesLeftSvgs,
+ wearablesRightSvgs,
+ wearablesBackSvgs,
+ wearablesLeftSleeveSvgs,
+ wearablesRightSleeveSvgs,
+ wearablesBackSleeveSvgs,
+} from "../svgs/wearables-sides";
+
+import { aavegotchiSvgs } from "../svgs/aavegotchi-typescript";
+import { run } from "hardhat";
+import { allSideViewDimensions } from "../svgs/sideViewDimensions";
+import { convertSideDimensionsToTaskFormat } from "../tasks/updateItemSideDimensions";
+import { allExceptions } from "../svgs/allExceptions";
+import { convertExceptionsToTaskFormat } from "../tasks/updateWearableExceptions";
+
+const diamond = require("../js/diamond-util/src/index.js");
+const { collaterals } = require("./testCollateralTypes.js");
+
+function addCommas(nStr: any) {
+ nStr += "";
+ const x = nStr.split(".");
+ let x1 = x[0];
+ const x2 = x.length > 1 ? "." + x[1] : "";
+ var rgx = /(\d+)(\d{3})/;
+ while (rgx.test(x1)) {
+ x1 = x1.replace(rgx, "$1" + "," + "$2");
+ }
+ return x1 + x2;
+}
+
+function strDisplay(str: any) {
+ return addCommas(str.toString());
+}
+
+async function main() {
+ if (!["hardhat", "localhost", "amoy", "base-sepolia"].includes(network.name)) {
+ throw Error("No network settings for " + network.name);
+ }
+
+ //amoy
+ const ghstContract = "0xB40B75b4a8e5153357b3e5e4343d997B1a1019f9";
+ const ghstStakingDiamondAddress =
+ "0xae83d5fc564Ef58224e934ba4Df72a100d5082a0";
+ const realmDiamondAddress = "0x5a4faEb79951bAAa0866B72fD6517E693c8E4620";
+ const installationDiamondAddress =
+ "0x514b7c55FB3DFf3533B58D85CD25Ba04bb30612D";
+ const tileDiamondAddress = "0xCa6F4Ef19a1Beb9BeF12f64b395087E5680bcB22";
+ const fakeGotchiArtDiamondAddress =
+ "0x330088c3372f4F78cF023DF16E1e1564109191dc"; //todo
+ const fakeGotchiCardDiamondAddress =
+ "0x9E282FE4a0be6A0C4B9f7d9fEF10547da35c52EA"; //todo
+
+ const name = "Aavegotchi";
+ const symbol = "GOTCHI";
+
+ const childChainManager = "0xb5505a6d998549090530911180f38aC5130101c6";
+ const vrfCoordinatorAmoy = "0x7E10652Cb79Ba97bC1D0F38a1e8FaD8464a8a908"; // todo
+ const keyHash =
+ "0x3f631d5ec60a0ce16203bcd6aff7ffbc423e22e452786288e172d467354304c8"; // todo
+ const subscriptionIdAmoy = BigNumber.from(4534367);
+
+ const fee = ethers.utils.parseEther("0.0001");
+
+ const accounts = await ethers.getSigners();
+ const ownerAddress = await accounts[0].getAddress();
+
+ console.log("Owner: " + ownerAddress);
+
+ const dao = ownerAddress; // 'todo'
+ const daoTreasury = ownerAddress;
+ const rarityFarming = ownerAddress; // 'todo'
+ const pixelCraft = ownerAddress; // 'todo'
+ const itemManagers = [ownerAddress]; // 'todo'
+
+ const initArgs = [
+ [
+ dao,
+ daoTreasury,
+ pixelCraft,
+ rarityFarming,
+ ghstContract,
+ keyHash,
+ subscriptionIdAmoy,
+ vrfCoordinatorAmoy,
+ childChainManager,
+ name,
+ symbol,
+ ],
+ ];
+
+ const gasLimit = 12300000;
+ let totalGasUsed = ethers.BigNumber.from("0");
+ let tx;
+ let receipt;
+
+ async function deployFacets(...facets: any[]) {
+ const instances = [];
+ for (let facet of facets) {
+ let constructorArgs = [];
+ if (Array.isArray(facet)) {
+ [facet, constructorArgs] = facet;
+ }
+ const factory: any = await ethers.getContractFactory(facet);
+ const facetInstance = await factory.deploy(...constructorArgs);
+ await facetInstance.deployed();
+ const tx = facetInstance.deployTransaction;
+ const receipt = await tx.wait();
+ console.log(`${facet} deploy gas used:` + strDisplay(receipt.gasUsed));
+ totalGasUsed = totalGasUsed.add(receipt.gasUsed);
+ instances.push(facetInstance);
+ }
+ return instances;
+ }
+ let [
+ bridgeFacet,
+ aavegotchiFacet,
+ aavegotchiGameFacet,
+ svgFacet,
+ itemsFacet,
+ itemsTransferFacet,
+ collateralFacet,
+ daoFacet,
+ vrfFacet,
+ shopFacet,
+ metaTransactionsFacet,
+ erc1155MarketplaceFacet,
+ erc721MarketplaceFacet,
+ escrowFacet,
+ gotchiLendingFacet,
+ lendingGetterAndSetterFacet,
+ marketplaceGetterFacet,
+ svgViewsFacet,
+ wearableSetsFacet,
+ whitelistFacet,
+ peripheryFacet,
+ merkleDropFacet,
+ erc721BuyorderFacet,
+ itemsRolesRegistryFacet,
+ voucherMigrationFacet,
+ erc1155BuyOrderFacet,
+ polygonXGeistBridgeFacet,
+ ] = await deployFacets(
+ "contracts/Aavegotchi/facets/BridgeFacet.sol:BridgeFacet",
+ "contracts/Aavegotchi/facets/AavegotchiFacet.sol:AavegotchiFacet",
+ "AavegotchiGameFacet",
+ "SvgFacet",
+ "contracts/Aavegotchi/facets/ItemsFacet.sol:ItemsFacet",
+ "ItemsTransferFacet",
+ "CollateralFacet",
+ "DAOFacet",
+ "VrfFacet",
+ "ShopFacet",
+ "MetaTransactionsFacet",
+ "ERC1155MarketplaceFacet",
+ "ERC721MarketplaceFacet",
+ "EscrowFacet",
+ "GotchiLendingFacet",
+ "LendingGetterAndSetterFacet",
+ "MarketplaceGetterFacet",
+ "SvgViewsFacet",
+ "WearableSetsFacet",
+ "WhitelistFacet",
+ "PeripheryFacet",
+ "MerkleDropFacet",
+ "ERC721BuyOrderFacet",
+ "ItemsRolesRegistryFacet",
+ "VoucherMigrationFacet",
+ "ERC1155BuyOrderFacet",
+ "PolygonXGeistBridgeFacet"
+ );
+
+ const aavegotchiDiamond = await diamond.deploy({
+ diamondName: "AavegotchiDiamond",
+ initDiamond: "contracts/Aavegotchi/InitDiamond.sol:InitDiamond",
+ facets: [
+ ["BridgeFacet", bridgeFacet],
+ ["AavegotchiFacet", aavegotchiFacet],
+ ["AavegotchiGameFacet", aavegotchiGameFacet],
+ ["SvgFacet", svgFacet],
+ ["ItemsFacet", itemsFacet],
+ ["ItemsTransferFacet", itemsTransferFacet],
+ ["CollateralFacet", collateralFacet],
+ ["DAOFacet", daoFacet],
+ ["VrfFacet", vrfFacet],
+ ["ShopFacet", shopFacet],
+ ["MetaTransactionsFacet", metaTransactionsFacet],
+ ["ERC1155MarketplaceFacet", erc1155MarketplaceFacet],
+ ["ERC721MarketplaceFacet", erc721MarketplaceFacet],
+ ["EscrowFacet", escrowFacet],
+ ["GotchiLendingFacet", gotchiLendingFacet],
+ ["LendingGetterAndSetterFacet", lendingGetterAndSetterFacet],
+ ["MarketplaceGetterFacet", marketplaceGetterFacet],
+ ["SvgViewsFacet", svgViewsFacet],
+ ["WearableSetsFacet", wearableSetsFacet],
+ ["WhitelistFacet", whitelistFacet],
+ ["PeripheryFacet", peripheryFacet],
+ ["MerkleDropFacet", merkleDropFacet],
+ ["ERC721BuyOrderFacet", erc721BuyorderFacet],
+ ["ItemsRolesRegistryFacet", itemsRolesRegistryFacet],
+ ["VoucherMigrationFacet", voucherMigrationFacet],
+ ["ERC1155BuyOrderFacet", erc1155BuyOrderFacet],
+ ["PolygonXGeistBridgeFacet", polygonXGeistBridgeFacet],
+ ],
+ owner: ownerAddress,
+ args: initArgs,
+ });
+ console.log("Aavegotchi diamond address:" + aavegotchiDiamond.address);
+
+ tx = aavegotchiDiamond.deployTransaction;
+ receipt = await tx.wait();
+ console.log(
+ "Aavegotchi diamond deploy gas used:" + strDisplay(receipt.gasUsed)
+ );
+ totalGasUsed = totalGasUsed.add(receipt.gasUsed);
+
+ const deets = await vrfFacet.getVrfInfo();
+ console.log("Vrf info:", deets);
+
+ // wearable diamond
+
+ let [eventhandlerFacet, wearablesFacet] = await deployFacets(
+ "contracts/Aavegotchi/WearableDiamond/facets/EventHandlerFacet.sol:EventHandlerFacet",
+ "contracts/Aavegotchi/WearableDiamond/facets/WearablesFacet.sol:WearablesFacet"
+ );
+
+ //get constructor args from aavegotchi diamond
+ const [cutAddress, loupeAddress, ownershipAddress] =
+ await aavegotchiDiamond.getDefaultFacetAddresses();
+
+ const wearableDiamond = await diamond.deployWithoutInit({
+ diamondName: "WearableDiamond",
+ facets: [
+ ["EventHandlerFacet", eventhandlerFacet],
+ ["WearablesFacet", wearablesFacet],
+ ],
+ args: [
+ ownerAddress,
+ cutAddress,
+ loupeAddress,
+ ownershipAddress,
+ aavegotchiDiamond.address,
+ ],
+ });
+
+ console.log("Wearable diamond address:" + wearableDiamond.address);
+
+ tx = wearableDiamond.deployTransaction;
+ receipt = await tx.wait();
+ console.log(
+ "Wearable diamond deploy gas used:" + strDisplay(receipt.gasUsed)
+ );
+
+ totalGasUsed = totalGasUsed.add(receipt.gasUsed);
+
+ peripheryFacet = await ethers.getContractAt(
+ "PeripheryFacet",
+ aavegotchiDiamond.address
+ );
+
+ tx = await peripheryFacet.setPeriphery(wearableDiamond.address);
+ receipt = await tx.wait();
+ if (!receipt.status) {
+ throw Error(`Error:: ${tx.hash}`);
+ }
+ console.log(
+ "Setting wearable diamond gas used::" + strDisplay(receipt.gasUsed)
+ );
+ totalGasUsed = totalGasUsed.add(receipt.gasUsed);
+
+ // forge diamond
+ let [forgeFacet, forgeDaoFacet, forgeTokenFacet, forgeVrfFacet] =
+ await deployFacets(
+ "contracts/Aavegotchi/ForgeDiamond/facets/ForgeFacet.sol:ForgeFacet",
+ "contracts/Aavegotchi/ForgeDiamond/facets/ForgeDAOFacet.sol:ForgeDAOFacet",
+ "contracts/Aavegotchi/ForgeDiamond/facets/ForgeTokenFacet.sol:ForgeTokenFacet",
+ "contracts/Aavegotchi/ForgeDiamond/facets/ForgeVRFFacet.sol:ForgeVRFFacet"
+ );
+
+ const forgeDiamond = await diamond.deployWithoutInit({
+ diamondName: "ForgeDiamond",
+ facets: [
+ ["ForgeFacet", forgeFacet],
+ ["ForgeDAOFacet", forgeDaoFacet],
+ ["ForgeTokenFacet", forgeTokenFacet],
+ ["ForgeVRFFacet", forgeVrfFacet],
+ ],
+ args: [
+ ownerAddress,
+ cutAddress,
+ loupeAddress,
+ ownershipAddress,
+ aavegotchiDiamond.address,
+ wearableDiamond.address,
+ ],
+ });
+
+ console.log("Forge diamond address:" + forgeDiamond.address);
+ tx = wearableDiamond.deployTransaction;
+ receipt = await tx.wait();
+ console.log(
+ "Wearable diamond deploy gas used:" + strDisplay(receipt.gasUsed)
+ );
+ totalGasUsed = totalGasUsed.add(receipt.gasUsed);
+
+ // get facets
+ daoFacet = await ethers.getContractAt("DAOFacet", aavegotchiDiamond.address);
+ aavegotchiGameFacet = await ethers.getContractAt(
+ "AavegotchiGameFacet",
+ aavegotchiDiamond.address
+ );
+ erc1155MarketplaceFacet = await ethers.getContractAt(
+ "ERC1155MarketplaceFacet",
+ aavegotchiDiamond.address
+ );
+ erc721MarketplaceFacet = await ethers.getContractAt(
+ "ERC721MarketplaceFacet",
+ aavegotchiDiamond.address
+ );
+
+ svgFacet = await ethers.getContractAt("SvgFacet", aavegotchiDiamond.address);
+ peripheryFacet = await ethers.getContractAt(
+ "PeripheryFacet",
+ aavegotchiDiamond.address
+ );
+
+ // add item managers
+ console.log("Adding item managers");
+ tx = await daoFacet.addItemManagers(itemManagers, { gasLimit: gasLimit });
+ console.log("Adding item managers tx:", tx.hash);
+ receipt = await tx.wait();
+ if (!receipt.status) {
+ throw Error(`Adding item manager failed: ${tx.hash}`);
+ }
+
+ // // create new haunt and upload payloads
+ let initialHauntSize = "10000";
+ let portalPrice = ethers.utils.parseEther("0.1"); //0.1ghst/portal
+ tx = await daoFacet.createHaunt(initialHauntSize, portalPrice, "0x000000", {
+ gasLimit: gasLimit,
+ });
+ receipt = await tx.wait();
+ console.log("Haunt created:" + strDisplay(receipt.gasUsed));
+ totalGasUsed = totalGasUsed.add(receipt.gasUsed);
+
+ // add collateral info for haunt
+ console.log("Adding Collateral Types", collaterals);
+
+ tx = await daoFacet.addCollateralTypes(1, collaterals, {
+ gasLimit: gasLimit,
+ });
+ receipt = await tx.wait();
+ console.log("Add Collateral Types gas used::" + strDisplay(receipt.gasUsed));
+ totalGasUsed = totalGasUsed.add(receipt.gasUsed);
+
+ // add item types
+
+ //convert all itemtypes to itemTypeNew
+ let itemTypes2: ItemTypeInputNew[] = [];
+ for (let i = 0; i < allItemTypes.length; i++) {
+ itemTypes2.push(toItemTypeInputNew(allItemTypes[i]));
+ }
+ const itemTypes = getItemTypes(itemTypes2, ethers);
+ console.log("Adding", itemTypes2.length, "Item Types");
+ let step = 20;
+ let totalItems = itemTypes.length;
+ let totalBatches = Math.ceil(totalItems / step);
+
+ for (let i = 0; i < totalBatches; i++) {
+ const start = step * i;
+ const end = start + step;
+ const batch = itemTypes.slice(start, end); // Get current batch
+
+ let tx = await daoFacet.addItemTypes(batch, { gasLimit: gasLimit });
+ let receipt = await tx.wait();
+
+ // const itemIds = [];
+ // const quantities = [];
+ // batch.forEach((itemType) => {
+ // itemIds.push(itemType.svgId);
+ // quantities.push(itemType.maxQuantity);
+ // });
+ // tx = await daoFacet.mintItems(ownerAddress, itemIds, quantities , { gasLimit: gasLimit });
+ // receipt = await tx.wait();
+
+ if (!receipt.status) {
+ throw Error(`Error:: ${tx.hash}`);
+ }
+
+ console.log(
+ `Adding Item Types Batch ${
+ i + 1
+ } of ${totalBatches}, gas used:: ${strDisplay(receipt.gasUsed)}`
+ );
+ totalGasUsed = totalGasUsed.add(receipt.gasUsed);
+ }
+ console.log("Finished adding itemTypes");
+
+ // add wearable types sets
+ console.log("Adding ", wearableSetArrays.length, "Wearable Sets");
+ step = 50;
+ totalBatches = Math.ceil(wearableSetArrays.length / step);
+
+ for (let i = 0; i < totalBatches; i++) {
+ const start = step * i;
+ const end = start + step;
+ const batch = wearableSetArrays.slice(start, end);
+
+ const tx = await daoFacet.addWearableSets(batch, { gasLimit: gasLimit });
+
+ const receipt = await tx.wait();
+ console.log(
+ `Adding Wearable Sets Batch ${
+ i + 1
+ } of ${totalBatches}, gas used:: ${strDisplay(receipt.gasUsed)}`
+ );
+
+ if (!receipt.status) {
+ throw Error(`Error:: ${tx.hash}`);
+ }
+
+ totalGasUsed = totalGasUsed.add(receipt.gasUsed);
+ }
+
+ //add sideview dimensions in batches of 200
+ step = 200;
+ console.log("adding", allSideViewDimensions.length, "sideviews");
+ let sliceStep = Math.ceil(allSideViewDimensions.length / step);
+
+ for (let i = 0; i < sliceStep; i++) {
+ const start = step * i;
+ const end = start + step;
+ const batch = allSideViewDimensions.slice(start, end);
+ console.log(`Adding Sideview Dimensions (${i + 1} / ${sliceStep})`);
+ await run(
+ "updateItemSideDimensions",
+ convertSideDimensionsToTaskFormat(batch, aavegotchiDiamond.address)
+ );
+ }
+
+ //add sideview exceptions in batches of 100
+ step = 100;
+ console.log("adding", allExceptions.length, "exceptions");
+ sliceStep = Math.ceil(allExceptions.length / step);
+
+ for (let i = 0; i < sliceStep; i++) {
+ const start = sliceStep * i;
+ const end = start + sliceStep;
+ const slice = allExceptions.slice(
+ start,
+ Math.min(end, allExceptions.length)
+ );
+ console.log(`Adding Sideview Exceptions (${i + 1} / ${sliceStep}) `);
+ const tx = await run(
+ "updateWearableExceptions",
+ convertExceptionsToTaskFormat(slice, aavegotchiDiamond.address)
+ );
+ }
+
+ console.log("Upload SVGs");
+
+ const { eyeShapeSvgs } = require("../svgs/eyeShapes.js");
+ const collateralsSvgs = [
+ '',
+ ];
+ const collateralsLeftSvgs = [
+ '',
+ ];
+ const collateralsRightSvgs = [
+ '',
+ ];
+
+ console.log("uploading portal svgs");
+ await uploadSvgs(svgFacet, openedPortals, "portal-open", ethers);
+ await uploadSvgs(svgFacet, closedPortals, "portal-closed", ethers);
+
+ console.log("uploading aavegotchiSvgs");
+ await uploadSvgs(svgFacet, aavegotchiSvgs, "aavegotchi", ethers);
+ console.log("uploading collaterals");
+ await uploadSvgs(svgFacet, collateralsSvgs, "collaterals", ethers);
+ console.log("uploading eyeShapes");
+ await uploadSvgs(svgFacet, eyeShapeSvgs, "eyeShapes", ethers);
+ console.log("uploading aavegotchiSideSvgsLeft");
+ await uploadSvgs(
+ svgFacet,
+ aavegotchiSideSvgs.left,
+ "aavegotchi-left",
+ ethers
+ );
+ console.log("uploading aavegotchiSideSvgsRight");
+ await uploadSvgs(
+ svgFacet,
+ aavegotchiSideSvgs.right,
+ "aavegotchi-right",
+ ethers
+ );
+ console.log("uploading aavegotchiSideSvgsBack");
+ await uploadSvgs(
+ svgFacet,
+ aavegotchiSideSvgs.back,
+ "aavegotchi-back",
+ ethers
+ );
+ console.log("uploading collateral-side svgs");
+ await uploadSvgs(svgFacet, collateralsLeftSvgs, "collaterals-left", ethers);
+ await uploadSvgs(svgFacet, collateralsRightSvgs, "collaterals-right", ethers);
+ await uploadSvgs(svgFacet, [""], "collaterals-back", ethers);
+ await uploadSvgs(svgFacet, eyeShapesLeftSvgs, "eyeShapes-left", ethers);
+ await uploadSvgs(svgFacet, eyeShapesRightSvgs, "eyeShapes-right", ethers);
+ await uploadSvgs(
+ svgFacet,
+ Array(eyeShapeSvgs.length).fill(""),
+ "eyeShapes-back",
+ ethers
+ );
+
+ const { sleeves, wearables } = getWearables();
+
+ const svgsArray: string[] = wearables;
+ const sleeveSvgsArray: SleeveObject[] = sleeves;
+
+ console.log("Uploading wearables");
+ await uploadSvgs(svgFacet, svgsArray, "wearables", ethers);
+ console.log("Uploading sleeves");
+ await uploadSvgs(
+ svgFacet,
+ sleeveSvgsArray.map((value) => value.svg),
+ "sleeves",
+ ethers
+ );
+
+ //uploading sideviews
+
+ console.log("Uploading wearablesleft");
+ await uploadSvgs(
+ svgFacet,
+ wearablesLeftSvgs as string[],
+ "wearables-left",
+ ethers
+ );
+ console.log("Uploading wearablesRight");
+ await uploadSvgs(
+ svgFacet,
+ wearablesRightSvgs as string[],
+ "wearables-right",
+ ethers
+ );
+ console.log("Uploading wearablesBack");
+ await uploadSvgs(
+ svgFacet,
+ wearablesBackSvgs as string[],
+ "wearables-back",
+ ethers
+ );
+ console.log("Uploading wearablesLeftSleeve");
+ await uploadSvgs(svgFacet, wearablesLeftSleeveSvgs, "sleeves-left", ethers);
+ console.log("Uploading wearablesRightSleeve");
+ await uploadSvgs(svgFacet, wearablesRightSleeveSvgs, "sleeves-right", ethers);
+ console.log("Uploading wearablesBackSleeve");
+ await uploadSvgs(svgFacet, wearablesBackSleeveSvgs, "sleeves-back", ethers);
+ console.log("Upload Done");
+
+ interface SleeveInput {
+ sleeveId: BigNumberish;
+ wearableId: BigNumberish;
+ }
+ let sleevesSvgId: number = 0; // TODO
+ let sleevesInput: SleeveInput[] = [];
+ for (const sleeve of sleeveSvgsArray) {
+ sleevesInput.push({
+ sleeveId: sleevesSvgId,
+ wearableId: sleeve.id,
+ });
+ sleevesSvgId++;
+ }
+
+ console.log("Associating sleeves svgs with body wearable svgs.");
+ tx = await svgFacet.setSleeves(sleevesInput);
+ receipt = await tx.wait();
+ if (!receipt.status) {
+ throw Error(`Error:: ${tx.hash}`);
+ }
+ console.log("Sleeves associating gas used::" + strDisplay(receipt.gasUsed));
+ totalGasUsed = totalGasUsed.add(receipt.gasUsed);
+
+ await setForgeProperties(forgeDiamond.address);
+ tx = await daoFacet.setForge(forgeDiamond.address, { gasLimit: gasLimit });
+ receipt = await tx.wait();
+ console.log("Forge diamond set:" + strDisplay(receipt.gasUsed));
+ totalGasUsed = totalGasUsed.add(receipt.gasUsed);
+
+ // add erc721 and 1155 categories
+ // console.log("Adding ERC721 categories");
+ // const erc721Categories = [
+ // {
+ // erc721TokenAddress: realmDiamondAddress,
+ // category: 4,
+ // },
+ // {
+ // erc721TokenAddress: fakeGotchiArtDiamondAddress,
+ // category: 5,
+ // },
+ // ];
+ // tx = await erc721MarketplaceFacet.setERC721Categories(erc721Categories, {
+ // gasLimit: gasLimit,
+ // });
+ // receipt = await tx.wait();
+ // if (!receipt.status) {
+ // throw Error(`Error:: ${tx.hash}`);
+ // }
+ // console.log(
+ // "Adding ERC721 categories gas used::" + strDisplay(receipt.gasUsed)
+ // );
+ // totalGasUsed = totalGasUsed.add(receipt.gasUsed);
+ //
+ // console.log("Adding ERC1155 categories");
+ // const erc1155Categories = [];
+ // for (let i = 0; i < 6; i++) {
+ // erc1155Categories.push({
+ // erc1155TokenAddress: ghstStakingDiamondAddress,
+ // erc1155TypeId: i,
+ // category: 3,
+ // });
+ // }
+ // [
+ // 1, 141, 142, 143, 144, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155,
+ // 156,
+ // ].forEach((id) => {
+ // erc1155Categories.push({
+ // erc1155TokenAddress: installationDiamondAddress,
+ // erc1155TypeId: id,
+ // category: 4,
+ // });
+ // });
+ // Array.from({ length: 31 }, (_, index) => index + 1).forEach((id) => {
+ // erc1155Categories.push({
+ // erc1155TokenAddress: tileDiamondAddress,
+ // erc1155TypeId: id,
+ // category: 5,
+ // });
+ // });
+ // erc1155Categories.push({
+ // erc1155TokenAddress: fakeGotchiCardDiamondAddress,
+ // erc1155TypeId: 0,
+ // category: 6,
+ // });
+ //
+ // const offset = 1_000_000_000;
+ // const alloyCategory = 7;
+ // const geodesCategory = 9;
+ // const essenceCategory = 10;
+ // const coresCategory = 11;
+ // const alloyIds = [offset];
+ // const essenceIds = [offset + 1];
+ // const geodeIds = []; //[offset + 2, offset +3, offset+4, offset+5, offset+6, offset+7];
+ // for (let i = offset + 2; i < offset + 8; i++) {
+ // geodeIds.push(i);
+ // }
+ // const coreIds = [];
+ // for (let i = offset + 8; i < offset + 44; i++) {
+ // coreIds.push(i);
+ // }
+ // const forgeFinalArray = [
+ // [alloyCategory, alloyIds],
+ // [geodesCategory, geodeIds],
+ // [essenceCategory, essenceIds],
+ // [coresCategory, coreIds],
+ // ];
+ // forgeFinalArray.forEach((el) => {
+ // const category = el[0];
+ // const toAdd = el[1] as number[];
+ //
+ // for (let index = 0; index < toAdd.length; index++) {
+ // erc1155Categories.push({
+ // erc1155TokenAddress: forgeDiamond.address,
+ // erc1155TypeId: toAdd[index],
+ // category: category,
+ // });
+ // }
+ // });
+ //
+ // tx = await erc1155MarketplaceFacet.setERC1155Categories(erc1155Categories, {
+ // gasLimit: gasLimit,
+ // });
+ // receipt = await tx.wait();
+ // if (!receipt.status) {
+ // throw Error(`Error:: ${tx.hash}`);
+ // }
+ // console.log(
+ // "Adding ERC1155 categories gas used::" + strDisplay(receipt.gasUsed)
+ // );
+ // totalGasUsed = totalGasUsed.add(receipt.gasUsed);
+ //
+ // set realm address
+ // tx = await aavegotchiGameFacet.setRealmAddress(realmDiamondAddress, {
+ // gasLimit: gasLimit,
+ // });
+ // receipt = await tx.wait();
+ // console.log("Realm diamond set:" + strDisplay(receipt.gasUsed));
+ // totalGasUsed = totalGasUsed.add(receipt.gasUsed);
+
+ console.log("Total gas used: " + strDisplay(totalGasUsed));
+}
+
+// We recommend this pattern to be able to use async/await everywhere
+// and properly handle errors.
+if (require.main === module) {
+ main()
+ .then(() => process.exit(0))
+ .catch((error) => {
+ console.error(error);
+ process.exit(1);
+ });
+}
+
+exports.deployProject = main;
diff --git a/scripts/geistBridge/bridgeTest.ts b/scripts/geistBridge/bridgeTest.ts
new file mode 100644
index 000000000..46f3c5c27
--- /dev/null
+++ b/scripts/geistBridge/bridgeTest.ts
@@ -0,0 +1,111 @@
+/* global ethers hre */
+
+import { ethers, network } from "hardhat";
+import { maticDiamondAddress } from "../helperFunctions";
+
+export default async function main() {
+ let diamondAddress;
+ let gotchiBridgeAddress;
+ let gotchiConnectorAddress;
+ let itemBridgeAddress;
+ let itemConnectorAddress;
+ if (network.name === "base-sepolia") {
+ diamondAddress = "0x87C969d083189927049f8fF3747703FB9f7a8AEd"
+ // vault address
+ gotchiBridgeAddress = "0x0e915A936d4a7E300B749112DA80D047Bf580DA7"
+ gotchiConnectorAddress = "0x06C845Df424C9DD61Eb4D59ceCa631b597CC3c5F"
+ itemBridgeAddress = "0xde94E671f4612D0F020851173e9fD99d3A6Cc9F3"
+ itemConnectorAddress = "0xff2b3CdaA9882b89c8d64a6904263A58c4644762"
+ } else if (network.name === "matic") {
+ diamondAddress = maticDiamondAddress
+ // TODO: connector address
+ gotchiBridgeAddress = ""
+ gotchiConnectorAddress = ""
+ itemBridgeAddress = ""
+ itemConnectorAddress = ""
+ } else {
+ throw Error("No network settings for " + network.name);
+ }
+
+ const bridgeFacet = await ethers.getContractAt("PolygonXGeistBridgeFacet", diamondAddress)
+ const aavegotchiFacet = await ethers.getContractAt("contracts/Aavegotchi/facets/AavegotchiFacet.sol:AavegotchiFacet", diamondAddress)
+ const svgFacet = await ethers.getContractAt("SvgFacet", diamondAddress)
+ const daoFacet = await ethers.getContractAt("DAOFacet", diamondAddress)
+ const itemsFacet = await ethers.getContractAt("contracts/Aavegotchi/facets/ItemsFacet.sol:ItemsFacet", diamondAddress)
+
+ const accounts = await ethers.getSigners();
+ const signer = accounts[0];
+ const gasLimit = 500000;
+ const gasPrice = 100000000000;
+ let tx;
+
+ // console.log(`Trying to approve to send gotchis/items.`);
+ // tx = await aavegotchiFacet.setApprovalForAll(itemBridgeAddress, true)
+ // console.log(`Wating for tx to be validated, tx hash: ${tx.hash}`)
+ // await tx.wait()
+
+ // aavegotchi bridging
+ for (let tokenId = 106; tokenId < 108; tokenId++) {
+ const gotchi = await aavegotchiFacet.getAavegotchi(tokenId)
+ console.log(`Gotchi: ${gotchi}`)
+ const svg = await svgFacet.getAavegotchiSvg(tokenId)
+ console.log(`Gotchi SVG: ${svg}`)
+
+ console.log(`Trying to approve to send a gotchi. Token Id: ${tokenId}`);
+ tx = await aavegotchiFacet.approve(gotchiBridgeAddress, tokenId)
+ console.log(`Wating for tx to be validated, tx hash: ${tx.hash}`)
+ await tx.wait()
+
+ console.log(`Trying to bridge a gotchi. Token Id:${tokenId}`);
+ tx = await bridgeFacet.bridgeGotchi(signer.address, tokenId, gasLimit, gotchiConnectorAddress, {gasPrice: gasPrice})
+ console.log(`Wating for tx to be validated, tx hash: ${tx.hash}`)
+ await tx.wait()
+ }
+
+ // item minting
+ // const mintTokenIds = [151, 152, 153, 210];
+ // const quantities = [20, 20, 20, 20];
+ // console.log(`Trying to mint items...`)
+ // tx = await daoFacet.mintItems(signer.address, mintTokenIds, quantities, {gasPrice: gasPrice})
+ // console.log(`Wating for tx to be validated, tx hash: ${tx.hash}`)
+ // await tx.wait()
+
+ // item bridging
+ // for (let tokenId = 1; tokenId < 30; tokenId++) {
+ // console.log(`Trying to bridge an item. Item Id:${tokenId}`)
+ // tx = await bridgeFacet.bridgeItem(signer.address, tokenId, 2, gasLimit, itemConnectorAddress, {gasPrice: gasPrice})
+ // console.log(`Wating for tx to be validated, tx hash: ${tx.hash}`)
+ // await tx.wait()
+ // }
+
+ // equip/unequip gotchi
+ // for (let tokenId = 106; tokenId < 107; tokenId++) {
+ // console.log(`Trying to equip/unequip a gotchi. Token Id: ${tokenId}`);
+ // // // equip all slots
+ // // tx = await itemsFacet.equipWearables(tokenId, [15, 13, 14, 10, 29, 12, 151, 0, 0, 0, 0, 0, 0, 0, 0, 0])
+ // // equip some slots
+ // tx = await itemsFacet.equipWearables(tokenId, [15, 0, 14, 0, 29, 0, 151, 0, 0, 0, 0, 0, 0, 0, 0, 0])
+ // // // unequip all
+ // // tx = await itemsFacet.equipWearables(tokenId, [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
+ // console.log(`Wating for tx to be validated, tx hash: ${tx.hash}`)
+ // await tx.wait()
+ // }
+
+ // check code
+ // console.log(`Fetching information of gotchis. Owner address:${signer.address}`);
+ // const gotchis = await aavegotchiFacet.allAavegotchisOfOwner(signer.address)
+ // console.log(`Gotchis: ${gotchis}`)
+}
+
+// We recommend this pattern to be able to use async/await everywhere
+// and properly handle errors.
+if (require.main === module) {
+ main()
+ .then(() => process.exit(0))
+ .catch((error) => {
+ console.error(error);
+ process.exit(1);
+ });
+}
+
+exports.deployProject = main;
diff --git a/scripts/geistBridge/configureBridge.ts b/scripts/geistBridge/configureBridge.ts
new file mode 100644
index 000000000..4e1abae17
--- /dev/null
+++ b/scripts/geistBridge/configureBridge.ts
@@ -0,0 +1,57 @@
+/* global ethers hre */
+
+import { ethers, network } from "hardhat";
+import { maticDiamondAddress } from "../helperFunctions";
+import { AMOY_DIAMOND } from "../../helpers/constants";
+
+export default async function main() {
+ const gasPrice = "70000000000";
+ let gotchiBridgeAddress;
+ let itemBridgeAddress;
+ let diamondAddress;
+ let tx;
+ if (network.name === "base-sepolia") {
+ diamondAddress = "0x87C969d083189927049f8fF3747703FB9f7a8AEd";
+ // vault address
+ gotchiBridgeAddress = "0x0e915A936d4a7E300B749112DA80D047Bf580DA7";
+ itemBridgeAddress = "0xde94E671f4612D0F020851173e9fD99d3A6Cc9F3";
+ } else if (network.name === "matic") {
+ diamondAddress = maticDiamondAddress;
+ // TODO: vault address
+ gotchiBridgeAddress = "";
+ itemBridgeAddress = "";
+ } else {
+ throw Error("No network settings for " + network.name);
+ }
+
+ const daoFacet = await ethers.getContractAt("DAOFacet", diamondAddress);
+
+ console.log(`Configuring gotchi bridge...`);
+ tx = await daoFacet.updateGotchiGeistBridge(gotchiBridgeAddress, {
+ gasPrice: gasPrice,
+ });
+ console.log(`Wating for tx to be validated, tx hash: ${tx.hash}`);
+ await tx.wait();
+
+ console.log(`Configuring items bridge...`);
+ tx = await daoFacet.updateItemGeistBridge(itemBridgeAddress, {
+ gasPrice: gasPrice,
+ });
+ console.log(`Wating for tx to be validated, tx hash: ${tx.hash}`);
+ await tx.wait();
+
+ console.log(`Bridge configured on ${network.name}.`);
+}
+
+// We recommend this pattern to be able to use async/await everywhere
+// and properly handle errors.
+if (require.main === module) {
+ main()
+ .then(() => process.exit(0))
+ .catch((error) => {
+ console.error(error);
+ process.exit(1);
+ });
+}
+
+exports.deployProject = main;
diff --git a/scripts/helperFunctions.ts b/scripts/helperFunctions.ts
index f00721555..0eef1affd 100644
--- a/scripts/helperFunctions.ts
+++ b/scripts/helperFunctions.ts
@@ -287,9 +287,8 @@ export async function getRelayerSigner(hre: HardhatRuntimeEnvironment) {
speed: "safeLow",
validForSeconds: 7200,
});
- } else if (hre.network.name === "tenderly") {
+ } else if (["tenderly", "base-sepolia", "amoy"].includes(hre.network.name)) {
//impersonate
- console.log("Using tenderly");
return (await hre.ethers.getSigners())[0];
} else {
throw Error("Incorrect network selected");
diff --git a/scripts/itemTypeHelpers.ts b/scripts/itemTypeHelpers.ts
index 96d2be8f3..8e00ae26c 100644
--- a/scripts/itemTypeHelpers.ts
+++ b/scripts/itemTypeHelpers.ts
@@ -24,11 +24,7 @@ export interface SideDimensions {
export interface Exceptions {
itemId: BigNumberish;
slotPosition: BigNumberish;
- side:
- | "wearables-back"
- | "wearables-left"
- | "wearables-right"
- | "wearables-front";
+ side: string;
exceptionBool: boolean;
}
@@ -80,19 +76,6 @@ export type rarityLevel =
| "mythical"
| "godlike";
-export type Author =
- | "GFA"
- | "z_tef"
- | "Laggin"
- | "XIBOT"
- | "xibot"
- | "oggysk"
- | "Oliver Spoon"
- | "[GFA] z_tef"
- | "THE FORGE"
- | "soju"
- | "SOJU";
-
export interface ItemTypeInputNew {
name: string;
description: string;
@@ -101,7 +84,7 @@ export interface ItemTypeInputNew {
canBeTransferred: boolean;
rarityLevel: rarityLevel;
setId: BigNumberish[];
- author: Author;
+ author: string;
dimensions: Dimensions;
allowedCollaterals: BigNumberish[];
ghstPrice: BigNumberish | BigNumberish;
@@ -123,6 +106,30 @@ export interface ItemTypeInputNew {
maxQuantity?: number;
}
+export function toItemTypeInputNew(item: ItemTypeInput): ItemTypeInputNew {
+ return {
+ name: item.name,
+ description: item.description,
+ svgId: item.svgId,
+ minLevel: item.minLevel,
+ canBeTransferred: item.canBeTransferred,
+ rarityLevel: maxQuantityToRarity(Number(item.maxQuantity)),
+ setId: item.setId,
+ author: item.author,
+ dimensions: item.dimensions,
+ allowedCollaterals: item.allowedCollaterals,
+ ghstPrice: item.ghstPrice,
+ traitModifiers: item.traitModifiers,
+ slotPositions: item.slotPositions,
+ category: item.category,
+ experienceBonus: item.experienceBonus,
+ kinshipBonus: item.kinshipBonus,
+ canPurchaseWithGhst: item.canPurchaseWithGhst,
+ maxQuantity: Number(item.maxQuantity),
+ totalQuantity: Number(item.totalQuantity),
+ };
+}
+
export interface ItemTypeOutput {
name: string;
description: string;
@@ -389,8 +396,8 @@ export function stringToSlotPositions(
false,
false,
false,
- true,
false,
+ true,
false,
false,
false,
@@ -434,6 +441,9 @@ export function calculateRarityScoreModifier(maxQuantity: number): number {
return 0;
}
+//exclude some tems from traitBooster checklist
+const excludedItems = [0, 26, 100, 105, 126, 127, 128, 129];
+
export function getItemTypes(
itemTypes: ItemTypeInputNew[],
ethers: any
@@ -458,9 +468,14 @@ export function getItemTypes(
Number(prev) + Math.abs(Number(cur));
let traitBoosters = itemType.traitModifiers.reduce(reducer, 0);
- if (itemType.category !== 1) {
+ if (
+ itemType.category !== 1 &&
+ !excludedItems.includes(Number(itemType.svgId))
+ ) {
if (traitBoosters !== rarityLevelToTraitBoosters(itemType.rarityLevel)) {
- throw Error(`Trait Booster for ${itemType.name} does not match rarity`);
+ throw Error(
+ `Trait Booster for ${itemType.name} does not match rarity`
+ );
}
}
@@ -540,6 +555,15 @@ function rarityLevelToMaxQuantity(rarityLevel: rarityLevel): number {
}
}
+export function maxQuantityToRarity(quantity: number) {
+ if (quantity >= 1000) return "common";
+ else if (quantity >= 500) return "uncommon";
+ else if (quantity >= 250) return "rare";
+ else if (quantity >= 100) return "legendary";
+ else if (quantity >= 10) return "mythical";
+ else return "godlike";
+}
+
export function rarityLevelToTraitBoosters(rarityLevel: rarityLevel): number {
switch (rarityLevel) {
case "common":
diff --git a/scripts/testCollateralTypes.js b/scripts/testCollateralTypes.js
index b57ae5150..43e17c694 100644
--- a/scripts/testCollateralTypes.js
+++ b/scripts/testCollateralTypes.js
@@ -1,20 +1,19 @@
-
const collaterals = [
-
{
- name: 'GHST',
- kovanAddress: '',
- mainnetAddress: '',
- hardhatAddress: '',
- mumbaiAddress: '',
- primaryColor: '#FF7D00',
- secondaryColor: '#F9D792',
- cheekColor: '#F4AF24',
+ name: "GHST",
+ kovanAddress: "",
+ mainnetAddress: "",
+ hardhatAddress: "",
+ mumbaiAddress: "",
+ amoyAddress: "0xF679b8D109b2d23931237Ce948a7D784727c0897",
+ primaryColor: "#FF7D00",
+ secondaryColor: "#F9D792",
+ cheekColor: "#F4AF24",
svgId: 0,
eyeShapeSvgId: 16,
modifiers: [0, 0, -1, 0, 0, 0],
- conversionRate: 1 // 1 DAI equals 1 DAI
- }
+ conversionRate: 1, // 1 DAI equals 1 DAI
+ },
/*
{
@@ -31,54 +30,69 @@ const collaterals = [
conversionRate: 1 // 1 DAI equals 1 DAI
},
*/
-]
+];
-function eightBitArrayToUint (array) {
- const uint = []
+function eightBitArrayToUint(array) {
+ const uint = [];
for (const num of array) {
- const value = ethers.BigNumber.from(num).toTwos(8)
- uint.unshift(value.toHexString().slice(2))
+ const value = ethers.BigNumber.from(num).toTwos(8);
+ uint.unshift(value.toHexString().slice(2));
}
- return ethers.BigNumber.from('0x' + uint.join(''))
+ return ethers.BigNumber.from("0x" + uint.join(""));
}
-function getCollaterals (network, ghstAddress, testAddress) {
- const collateralTypes = []
+function getCollaterals(network, ghstAddress) {
+ const collateralTypes = [];
for (const collateralType of collaterals) {
const collateralTypeInfo = {
- primaryColor:
- '0x' + collateralType.primaryColor.slice(1),
- secondaryColor:
- '0x' + collateralType.secondaryColor.slice(1),
- cheekColor:
- '0x' + collateralType.cheekColor.slice(1),
+ primaryColor: "0x" + collateralType.primaryColor.slice(1),
+ secondaryColor: "0x" + collateralType.secondaryColor.slice(1),
+ cheekColor: "0x" + collateralType.cheekColor.slice(1),
svgId: collateralType.svgId,
eyeShapeSvgId: collateralType.eyeShapeSvgId,
// modifiers: eightBitArrayToUint(collateralType.modifiers),
modifiers: collateralType.modifiers,
conversionRate: collateralType.conversionRate,
- delisted: false
+ delisted: false,
+ };
+ const item = {};
+ if (network === "kovan") {
+ item.collateralType = collateralType.kovanAddress;
+ } else if (network === "mumbai") {
+ item.collateralType = ghstAddress;
+ } else if (network === "hardhat" || network === "localhost") {
+ item.collateralType = ghstAddress;
+ // else if (collateralType.name === "TEST")
+ // item.collateralType = testAddress;
+ } else if (network === "mainnet") {
+ item.collateralType = collateralType.mainnetAddress;
+ } else if (network === "matic") {
+ item.collateralTypeInfo = collateralType.maticAddress;
+ } else if (network === "amoy") {
+ item.collateralTypeInfo = collateralType.amoyAddress;
}
- const item = {}
- if (network === 'kovan') {
- item.collateralType = collateralType.kovanAddress
- } else if (network === 'mumbai') {
- if (collateralType.name === 'GHST') {
- item.collateralType = ghstAddress
- }
- } else if (network === 'hardhat') {
- if (collateralType.name === 'GHST') item.collateralType = ghstAddress
- else if (collateralType.name === 'TEST') item.collateralType = testAddress
- } else if (network === 'mainnet') {
- item.collateralType = collateralType.mainnetAddress
- } else if (network === 'matic') {
- item.collateralTypeInfo = collateralType.maticAddress
- }
- item.collateralTypeInfo = collateralTypeInfo
- collateralTypes.push(item)
+ item.collateralTypeInfo = collateralTypeInfo;
+ collateralTypes.push(item);
}
-
- return collateralTypes
}
-exports.getCollaterals = getCollaterals
+//for rough tests only
+const collateralTypeInfo = [
+ {
+ collateralType: "0xF679b8D109b2d23931237Ce948a7D784727c0897",
+ collateralTypeInfo: {
+ primaryColor: "0x" + "#FF7D00".slice(1),
+ secondaryColor: "0x" + "#F9D792".slice(1),
+ cheekColor: "0x" + "#F4AF24".slice(1),
+ svgId: 0,
+ eyeShapeSvgId: 16,
+ modifiers: [0, 0, -1, 0, 0, 0],
+ conversionRate: 1, // 1 DAI equals 1 DAI
+ delisted: true,
+ },
+ },
+];
+
+exports.collaterals = collateralTypeInfo;
+
+//exports.getCollaterals = getCollaterals;
diff --git a/scripts/updates/batchMintGotchigangWearables.ts b/scripts/updates/batchMintGotchigangWearables.ts
index 554d24a7e..7dd42472c 100644
--- a/scripts/updates/batchMintGotchigangWearables.ts
+++ b/scripts/updates/batchMintGotchigangWearables.ts
@@ -14,7 +14,6 @@ import {
} from "../../typechain";
import { LedgerSigner } from "@anders-t/ethers-ledger";
import * as helpers from "@nomicfoundation/hardhat-network-helpers";
-import { WEARABLE_BASE_QUANTITIES } from "../../helpers/constants";
export const forgeAddresses = [
"0x4a478E4593A5D557dB640642c34Ae52800084451",
@@ -133,13 +132,7 @@ export async function batchMintGotchigangWearables() {
signer
)) as ForgeFacet;
- const totalAmounts = [
- WEARABLE_BASE_QUANTITIES.COMMON,
- WEARABLE_BASE_QUANTITIES.UNCOMMON,
- WEARABLE_BASE_QUANTITIES.RARE,
- WEARABLE_BASE_QUANTITIES.LEGENDARY,
- WEARABLE_BASE_QUANTITIES.MYTHICAL,
- ];
+ const totalAmounts = [1000, 500, 250, 100, 10];
const ids = Object.values(itemIds).flat();
const amounts = Object.entries(itemIds).flatMap(([rarity, ids]) =>
diff --git a/scripts/upgrades/upgrade-erc1155BuyOrderFacet.ts b/scripts/upgrades/upgrade-erc1155BuyOrderFacet.ts
index d8aac7387..ebb7c7642 100644
--- a/scripts/upgrades/upgrade-erc1155BuyOrderFacet.ts
+++ b/scripts/upgrades/upgrade-erc1155BuyOrderFacet.ts
@@ -5,6 +5,9 @@ import {
FacetsAndAddSelectors,
} from "../../tasks/deployUpgrade";
import { maticDiamondAddress, maticDiamondUpgrader } from "../helperFunctions";
+import { AMOY_DIAMON_OWNER, AMOY_DIAMOND } from "../../helpers/constants";
+
+export async function upgrade() {
export async function upgrade() {
@@ -19,6 +22,8 @@ export async function upgrade() {
removeSelectors: [],
},
{
+ facetName:
+ "contracts/Aavegotchi/facets/ERC1155MarketplaceFacet.sol:ERC1155MarketplaceFacet",
facetName: "ERC1155MarketplaceFacet",
addSelectors: [],
removeSelectors: [],
@@ -28,6 +33,11 @@ export async function upgrade() {
const joined = convertFacetAndSelectorsToString(facets);
const args: DeployUpgradeTaskArgs = {
+ diamondOwner: AMOY_DIAMON_OWNER,
+ diamondAddress: AMOY_DIAMOND,
+ facetsAndAddSelectors: joined,
+ useLedger: false,
+ useMultisig: false,
diamondOwner: maticDiamondUpgrader,
diamondAddress: maticDiamondAddress,
facetsAndAddSelectors: joined,
diff --git a/scripts/upgrades/upgrade-geistBridgeFacet.ts b/scripts/upgrades/upgrade-geistBridgeFacet.ts
new file mode 100644
index 000000000..4b0e48069
--- /dev/null
+++ b/scripts/upgrades/upgrade-geistBridgeFacet.ts
@@ -0,0 +1,57 @@
+import { ethers, run } from "hardhat";
+import {
+ convertFacetAndSelectorsToString,
+ DeployUpgradeTaskArgs,
+ FacetsAndAddSelectors,
+} from "../../tasks/deployUpgrade";
+import { maticDiamondAddress } from "../helperFunctions";
+
+export async function upgrade() {
+ const diamondOwner = "0x01F010a5e001fe9d6940758EA5e8c777885E351e";
+
+ const facets: FacetsAndAddSelectors[] = [
+ {
+ facetName: "PolygonXGeistBridgeFacet",
+ addSelectors: [
+ "function bridgeGotchi(address _receiver, uint256 _tokenId, uint256 _msgGasLimit, address _connector) external payable",
+ "function setMetadata(uint _tokenId, bytes memory _metadata) external",
+ "function bridgeItem(address _receiver, uint256 _tokenId, uint256 _amount, uint256 _msgGasLimit, address _connector) external payable",
+ ],
+ removeSelectors: [],
+ },
+ {
+ facetName: "DAOFacet",
+ addSelectors: [
+ "function updateGotchiGeistBridge(address _newBridge) external",
+ "function updateItemGeistBridge(address _newBridge) external",
+ ],
+ removeSelectors: [],
+ },
+ ];
+
+ const joined = convertFacetAndSelectorsToString(facets);
+
+ const args: DeployUpgradeTaskArgs = {
+ // diamondOwner: AMOY_DIAMOND_OWNER,
+ // diamondAddress: AMOY_DIAMOND,
+ diamondOwner: '0xd38Df837a1EAd12ee16f8b8b7E5F58703f841668',
+ diamondAddress: '0x87C969d083189927049f8fF3747703FB9f7a8AEd', // base-sepolia
+ facetsAndAddSelectors: joined,
+ useLedger: false,
+ useMultisig: false,
+ initAddress: ethers.constants.AddressZero,
+ initCalldata: "0x",
+ };
+
+ await run("deployUpgrade", args);
+}
+
+if (require.main === module) {
+ upgrade()
+ .then(() => process.exit(0))
+ // .then(() => console.log('upgrade completed') /* process.exit(0) */)
+ .catch((error) => {
+ console.error(error);
+ process.exit(1);
+ });
+}
diff --git a/svgs/aavegotchi.js b/svgs/aavegotchi.js
deleted file mode 100644
index 443921a53..000000000
--- a/svgs/aavegotchi.js
+++ /dev/null
@@ -1,29 +0,0 @@
-const fs = require('fs')
-const sealedClosedPortal = fs.readFileSync('./svgs/sealedClosedPortal.svg', 'utf8')
-const openPortal = fs.readFileSync('./svgs/openPortal.svg', 'utf8')
-
-const body = ''
-const cheeks = ''
-const mouth = ''
-const handsDownClosed = ''
-const handsDownOpen = ''
-const handsUp = ''
-const shadow = ''
-const aavegotchiBody = body + cheeks + mouth + shadow
-const hands = handsDownClosed + handsDownOpen + handsUp
-const aavegotchiSvgs = [
- // 0, sealed closed portal
- sealedClosedPortal,
- // 1, open portal
- openPortal,
- // 2 aavegotchi
- aavegotchiBody,
- // 3 hands
- hands,
-
- // 4 Background ETH
-
- ''
-]
-
-exports.aavegotchiSvgs = aavegotchiSvgs
diff --git a/svgs/aavegotchi.ts b/svgs/aavegotchi.ts
new file mode 100644
index 000000000..b09b4f254
--- /dev/null
+++ b/svgs/aavegotchi.ts
@@ -0,0 +1,37 @@
+const fs = require("fs");
+import { closedPortals } from "./portals";
+
+const openPortal = fs.readFileSync("./svgs/openPortal.svg", "utf8");
+
+const body =
+ '';
+const cheeks =
+ '';
+const mouth =
+ '';
+const handsDownClosed =
+ '';
+const handsDownOpen =
+ '';
+const handsUp =
+ '';
+const shadow =
+ '';
+const aavegotchiBody = body + cheeks + mouth + shadow;
+const hands = handsDownClosed + handsDownOpen + handsUp;
+export const aavegotchiSvgs = [
+ // 0, sealed closed portal
+ ...closedPortals,
+ // 1, open portal
+ openPortal,
+ // 2 aavegotchi
+ aavegotchiBody,
+ // 3 hands
+ hands,
+
+ // 4 Background ETH
+
+ '',
+];
+
+exports.aavegotchiSvgs = aavegotchiSvgs;
diff --git a/svgs/closedPortalSvg.js b/svgs/closedPortalSvg.js
deleted file mode 100644
index 35c66fd16..000000000
--- a/svgs/closedPortalSvg.js
+++ /dev/null
@@ -1,29 +0,0 @@
-/* eslint-disable prefer-const */
-
-const fs = require("fs");
-
-const portals = [];
-
-portal("h1-closed");
-portal("h1-closed");
-portal("h2-closed");
-
-function stripSvg(svg) {
- // removes svg tag
- if (svg.includes("viewBox")) {
- svg = svg.slice(svg.indexOf(">") + 1);
- svg = svg.replace("", "");
- }
- return svg;
-}
-
-function readSvg(name) {
- return stripSvg(fs.readFileSync(`./svgs/${name}.svg`, "utf8"));
-}
-
-function portal(name) {
- const svg = readSvg(name);
- portals.push(svg);
-}
-
-exports.closedPortalSvgs = portals;
diff --git a/svgs/portals.ts b/svgs/portals.ts
new file mode 100644
index 000000000..f22020c0c
--- /dev/null
+++ b/svgs/portals.ts
@@ -0,0 +1,35 @@
+/* eslint-disable prefer-const */
+
+const fs = require("fs");
+
+export const closedPortals: string[] = [];
+
+export const openedPortals: string[] = [];
+
+portal("h1-closed", true);
+portal("h2-closed", true);
+
+portal("h1-open", false);
+portal("h2-open", false);
+
+function stripSvg(svg: string) {
+ // removes svg tag
+ if (svg.includes("viewBox")) {
+ svg = svg.slice(svg.indexOf(">") + 1);
+ svg = svg.replace("", "");
+ }
+ return svg;
+}
+
+function readSvg(name: string) {
+ return stripSvg(fs.readFileSync(`./svgs/${name}.svg`, "utf8"));
+}
+
+function portal(name: string, closed: boolean) {
+ const svg: string = readSvg(name);
+ if (closed) {
+ closedPortals.push(svg);
+ } else {
+ openedPortals.push(svg);
+ }
+}
diff --git a/tasks/deployUpgrade.ts b/tasks/deployUpgrade.ts
index 316ba127d..e664f46d3 100644
--- a/tasks/deployUpgrade.ts
+++ b/tasks/deployUpgrade.ts
@@ -154,7 +154,11 @@ task(
});
signer = await hre.ethers.getSigner(owner);
- } else if (hre.network.name === "matic") {
+ } else if (
+ hre.network.name === "matic" ||
+ hre.network.name === "base-sepolia" ||
+ hre.network.name === "amoy"
+ ) {
if (useLedger) {
signer = new LedgerSigner(hre.ethers.provider, "m/44'/60'/1'/0/0");
} else signer = (await hre.ethers.getSigners())[0];
diff --git a/tasks/updateItemSideDimensions.ts b/tasks/updateItemSideDimensions.ts
index 621e78435..1e501a5a7 100644
--- a/tasks/updateItemSideDimensions.ts
+++ b/tasks/updateItemSideDimensions.ts
@@ -19,10 +19,12 @@ export interface UpdateItemSideDimensionsTaskArgs {
itemIds: string;
sides: string;
dimensions: string;
+ diamondAddress: string;
}
export function convertSideDimensionsToTaskFormat(
- dimensions: SideDimensions[]
+ dimensions: SideDimensions[],
+ diamondAddress: string
) {
const items: SideDimensions[] = [];
for (let index = 0; index < dimensions.length; index++) {
@@ -34,6 +36,7 @@ export function convertSideDimensionsToTaskFormat(
dimensions: convertDimensionsArrayToString(
items.map((item) => item.dimensions)
),
+ diamondAddress
};
return sideDimensionsTaskArgs;
}
@@ -69,7 +72,7 @@ task(
.addParam("itemIds", "Item IDs to update dimensions")
.addParam("sides", "Item side to be updated dimensions")
.addParam("dimensions", "New dimensions of each item")
-
+ .addOptionalParam("diamondAddress", "Diamond address to update", maticDiamondAddress)
.setAction(
async (
taskArgs: UpdateItemSideDimensionsTaskArgs,
@@ -85,7 +88,7 @@ task(
const signer: Signer = await getRelayerSigner(hre);
const svgViewsFacet = (await hre.ethers.getContractAt(
"SvgViewsFacet",
- maticDiamondAddress,
+ taskArgs.diamondAddress,
signer
)) as SvgViewsFacet;
diff --git a/tasks/updateWearableExceptions.ts b/tasks/updateWearableExceptions.ts
index f5fb33602..2ff932259 100644
--- a/tasks/updateWearableExceptions.ts
+++ b/tasks/updateWearableExceptions.ts
@@ -16,9 +16,10 @@ export interface UpdateExceptionTaskArg {
slotPositions: string;
sides: string;
exceptionBools: string;
+ diamondAddress: string;
}
-export function convertExceptionsToTaskFormat(exceptions: Exceptions[]) {
+export function convertExceptionsToTaskFormat(exceptions: Exceptions[], diamondAddress: string) {
const items: Exceptions[] = [];
for (let index = 0; index < exceptions.length; index++) {
items.push(exceptions[index]);
@@ -28,6 +29,7 @@ export function convertExceptionsToTaskFormat(exceptions: Exceptions[]) {
slotPositions: items.map((item: Exceptions) => item.slotPosition).join(),
sides: items.map((item: Exceptions) => item.side).join(),
exceptionBools: items.map((item: Exceptions) => item.exceptionBool).join(),
+ diamondAddress
};
console.log("Task Arg: ", exceptionsTaskArg);
@@ -74,6 +76,7 @@ task(
"exceptionBools",
"Determines whether or not wearble ID is exception"
)
+ .addOptionalParam("diamondAddress", "Diamond address to update", maticDiamondAddress)
.setAction(
async (
@@ -91,7 +94,7 @@ task(
const signer: Signer = await getRelayerSigner(hre);
const svgViewsFacet = (await hre.ethers.getContractAt(
"SvgViewsFacet",
- maticDiamondAddress,
+ taskArgs.diamondAddress,
signer
)) as SvgViewsFacet;