Skip to content

Commit d606d19

Browse files
committed
Merge branch 'feat/swapAndPlaceBuyOrders'
2 parents 56652a3 + b50fba4 commit d606d19

File tree

10 files changed

+1113
-139
lines changed

10 files changed

+1113
-139
lines changed
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
// SPDX-License-Identifier: MIT
2+
pragma solidity 0.8.1;
3+
4+
import {LibTokenSwap} from "../libraries/LibTokenSwap.sol";
5+
import {LibBuyOrder} from "../libraries/LibBuyOrder.sol";
6+
import {IERC20} from "../../shared/interfaces/IERC20.sol";
7+
import {Modifiers} from "../libraries/LibAppStorage.sol";
8+
9+
contract BuyOrderSwapFacet is Modifiers {
10+
struct ERC1155SwapParams {
11+
address tokenIn;
12+
uint256 swapAmount;
13+
uint256 minGhstOut;
14+
uint256 swapDeadline;
15+
address erc1155TokenAddress;
16+
uint256 erc1155TokenId;
17+
uint256 category;
18+
uint256 priceInWei;
19+
uint256 quantity;
20+
uint256 duration;
21+
address recipient;
22+
}
23+
24+
struct ERC721SwapParams {
25+
address tokenIn;
26+
uint256 swapAmount;
27+
uint256 minGhstOut;
28+
uint256 swapDeadline;
29+
address erc721TokenAddress;
30+
uint256 erc721TokenId;
31+
uint256 category;
32+
uint256 priceInWei;
33+
uint256 duration;
34+
address recipient;
35+
}
36+
37+
event SwapAndPlaceERC1155BuyOrder(address indexed buyer, uint256 indexed buyOrderId, address indexed tokenIn, uint256 ghstReceived);
38+
event SwapAndPlaceERC721BuyOrder(address indexed buyer, uint256 indexed buyOrderId, address indexed tokenIn, uint256 ghstReceived);
39+
40+
/**
41+
* @notice Swap tokens for GHST and immediately place a new ERC1155 buy order
42+
* @param params Packed swap and order parameters
43+
*/
44+
function swapAndPlaceERC1155BuyOrder(ERC1155SwapParams calldata params) external payable whenNotPaused {
45+
LibTokenSwap.validateSwapParams(params.tokenIn, params.swapAmount, params.minGhstOut, params.swapDeadline);
46+
47+
require(params.recipient == msg.sender, "ERC1155BuyOrderSwap: recipient must be msg.sender");
48+
49+
uint256 totalCost = LibBuyOrder.validateERC1155Params(params.erc1155TokenAddress, params.erc1155TokenId, params.priceInWei, params.quantity);
50+
51+
//assert ghst to be swapped to is enough
52+
require(params.minGhstOut >= totalCost, "ERC1155BuyOrderSwap: minGhstOut must cover total cost");
53+
54+
//perform swap
55+
uint256 ghstReceived = LibTokenSwap.swapForGHST(params.tokenIn, params.swapAmount, params.minGhstOut, params.swapDeadline, address(this));
56+
57+
require(ghstReceived >= totalCost, "ERC1155BuyOrderSwap: Insufficient GHST for purchase");
58+
59+
//place buy order
60+
uint256 buyOrderId = LibBuyOrder._placeERC1155BuyOrder(
61+
params.erc1155TokenAddress,
62+
params.erc1155TokenId,
63+
params.category,
64+
params.priceInWei,
65+
params.quantity,
66+
params.duration
67+
);
68+
69+
// Refund any excess GHST to the recipient using shared library, leave totalCost in the diamond
70+
LibTokenSwap.refundExcessGHST(params.recipient, ghstReceived, totalCost);
71+
72+
emit SwapAndPlaceERC1155BuyOrder(msg.sender, buyOrderId, params.tokenIn, ghstReceived);
73+
}
74+
75+
/**
76+
* @notice Swap tokens for GHST and immediately place a new ERC721 buy order
77+
* @param params Packed swap and order parameters
78+
* @param validationOptions Flags that determine additional validation logic
79+
*/
80+
function swapAndPlaceERC721BuyOrder(ERC721SwapParams calldata params, bool[] calldata validationOptions) external payable whenNotPaused {
81+
LibTokenSwap.validateSwapParams(params.tokenIn, params.swapAmount, params.minGhstOut, params.swapDeadline);
82+
83+
require(params.recipient == msg.sender, "ERC721BuyOrderSwap: recipient must be msg.sender");
84+
85+
uint256 totalCost = LibBuyOrder.validateERC721Params(
86+
params.erc721TokenAddress,
87+
params.erc721TokenId,
88+
params.category,
89+
params.priceInWei,
90+
validationOptions
91+
);
92+
93+
require(params.minGhstOut >= totalCost, "ERC721BuyOrderSwap: minGhstOut must cover total cost");
94+
95+
//perform swap and validate
96+
uint256 ghstReceived = LibTokenSwap.swapForGHST(params.tokenIn, params.swapAmount, params.minGhstOut, params.swapDeadline, address(this));
97+
98+
require(ghstReceived >= totalCost, "ERC721BuyOrderSwap: Insufficient GHST for purchase");
99+
100+
//place buy order
101+
uint256 buyOrderId = LibBuyOrder._placeERC721BuyOrder(
102+
params.erc721TokenAddress,
103+
params.erc721TokenId,
104+
params.category,
105+
params.priceInWei,
106+
params.duration,
107+
validationOptions
108+
);
109+
110+
// Refund any excess GHST to the recipient using shared library, leave totalCost in the diamond
111+
LibTokenSwap.refundExcessGHST(params.recipient, ghstReceived, totalCost);
112+
113+
emit SwapAndPlaceERC721BuyOrder(msg.sender, buyOrderId, params.tokenIn, ghstReceived);
114+
}
115+
}

contracts/Aavegotchi/facets/ERC1155BuyOrderFacet.sol

Lines changed: 2 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,6 @@ import {BaazaarSplit, LibSharedMarketplace, SplitAddresses} from "../libraries/L
1414
import "../WearableDiamond/interfaces/IEventHandlerFacet.sol";
1515

1616
contract ERC1155BuyOrderFacet is Modifiers {
17-
event ERC1155BuyOrderAdd(
18-
uint256 indexed buyOrderId,
19-
address indexed buyer,
20-
address erc1155TokenAddress,
21-
uint256 erc1155TokenId,
22-
uint256 indexed category,
23-
uint256 priceInWei,
24-
uint256 quantity,
25-
uint256 duration,
26-
uint256 time
27-
);
2817
event ERC1155BuyOrderCancel(uint256 indexed buyOrderId, uint256 time);
2918
event ERC1155BuyOrderExecute(
3019
uint256 indexed buyOrderId,
@@ -46,13 +35,7 @@ contract ERC1155BuyOrderFacet is Modifiers {
4635
uint256 _quantity,
4736
uint256 _duration
4837
) external whenNotPaused {
49-
uint256 cost = _quantity * _priceInWei;
50-
require(cost >= 1e15, "ERC1155BuyOrder: cost should be 0.001 GHST or larger");
51-
52-
require(LibSharedMarketplace.isContractWhitelisted(_erc1155TokenAddress), "ERC1155BuyOrder: contract not whitelisted");
53-
54-
require(!LibSharedMarketplace.isERC1155ListingExcluded(_erc1155TokenAddress, _erc1155TokenId), "ERC1155BuyOrder: token excluded");
55-
38+
uint256 cost = LibBuyOrder.validateERC1155Params(_erc1155TokenAddress, _erc1155TokenId, _priceInWei, _quantity);
5639
address sender = LibMeta.msgSender();
5740
uint256 ghstBalance = IERC20(s.ghstContract).balanceOf(sender);
5841

@@ -62,34 +45,7 @@ contract ERC1155BuyOrderFacet is Modifiers {
6245
LibERC20.transferFrom(s.ghstContract, sender, address(this), cost);
6346

6447
// Place new buy order
65-
s.nextERC1155BuyOrderId++;
66-
uint256 buyOrderId = s.nextERC1155BuyOrderId;
67-
68-
s.erc1155BuyOrders[buyOrderId] = ERC1155BuyOrder({
69-
buyOrderId: buyOrderId,
70-
buyer: sender,
71-
erc1155TokenAddress: _erc1155TokenAddress,
72-
erc1155TokenId: _erc1155TokenId,
73-
category: _category,
74-
priceInWei: _priceInWei,
75-
quantity: _quantity,
76-
timeCreated: block.timestamp,
77-
lastTimePurchased: 0,
78-
duration: _duration,
79-
completed: false,
80-
cancelled: false
81-
});
82-
emit ERC1155BuyOrderAdd(
83-
buyOrderId,
84-
sender,
85-
_erc1155TokenAddress,
86-
_erc1155TokenId,
87-
_category,
88-
_priceInWei,
89-
_quantity,
90-
_duration,
91-
block.timestamp
92-
);
48+
LibBuyOrder._placeERC1155BuyOrder(_erc1155TokenAddress, _erc1155TokenId, _category, _priceInWei, _quantity, _duration);
9349
}
9450

9551
function cancelERC1155BuyOrder(uint256 _buyOrderId) external whenNotPaused {

contracts/Aavegotchi/facets/ERC1155MarketplaceSwapFacet.sol

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
// SPDX-License-Identifier: MIT
22
pragma solidity 0.8.1;
33

4-
import {LibAppStorage, AppStorage} from "../libraries/LibAppStorage.sol";
54
import {LibERC1155Marketplace} from "../libraries/LibERC1155Marketplace.sol";
65
import {LibTokenSwap} from "../libraries/LibTokenSwap.sol";
7-
import {IERC20} from "../../shared/interfaces/IERC20.sol";
86
import {Modifiers} from "../libraries/LibAppStorage.sol";
97

108
contract ERC1155MarketplaceSwapFacet is Modifiers {
@@ -43,9 +41,6 @@ contract ERC1155MarketplaceSwapFacet is Modifiers {
4341
uint256 totalCost = quantity * priceInWei;
4442
require(minGhstOut >= totalCost, "ERC1155MarketplaceSwap: minGhstOut must cover total cost");
4543

46-
AppStorage storage s = LibAppStorage.diamondStorage();
47-
uint256 initialBalance = IERC20(s.ghstContract).balanceOf(address(this));
48-
4944
// Perform token swap to GHST
5045
uint256 ghstReceived = LibTokenSwap.swapForGHST(tokenIn, swapAmount, minGhstOut, swapDeadline, address(this));
5146

@@ -57,7 +52,7 @@ contract ERC1155MarketplaceSwapFacet is Modifiers {
5752
LibERC1155Marketplace.executeERC1155Listing(listingId, contractAddress, itemId, quantity, priceInWei, recipient, address(this));
5853

5954
// Refund any excess GHST to the recipient using shared library
60-
LibTokenSwap.refundExcessGHST(recipient, initialBalance);
55+
LibTokenSwap.refundExcessGHST(recipient, ghstReceived, totalCost);
6156

6257
{
6358
// Emit event in separate scope to avoid stack too deep

contracts/Aavegotchi/facets/ERC721BuyOrderFacet.sol

Lines changed: 9 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -15,18 +15,11 @@ import {BaazaarSplit, LibSharedMarketplace, SplitAddresses} from "../libraries/L
1515
import {CollateralEscrow} from "../CollateralEscrow.sol";
1616

1717
contract ERC721BuyOrderFacet is Modifiers {
18-
event ERC721BuyOrderAdded(
19-
uint256 indexed buyOrderId,
20-
address indexed buyer,
21-
address erc721TokenAddress,
22-
uint256 erc721TokenId,
23-
uint256 indexed category,
24-
uint256 priceInWei,
25-
uint256 duration,
26-
bytes32 validationHash,
27-
uint256 time
28-
);
29-
event ERC721BuyOrderCanceled(uint256 indexed buyOrderId, uint256 time);
18+
struct StatusesReturn {
19+
string status;
20+
uint256 buyOrderId;
21+
}
22+
3023
event ERC721BuyOrderExecuted(
3124
uint256 indexed buyOrderId,
3225
address indexed buyer,
@@ -42,11 +35,6 @@ contract ERC721BuyOrderFacet is Modifiers {
4235
require(buyOrder_.timeCreated != 0, "ERC721BuyOrder: ERC721 buyOrder does not exist");
4336
}
4437

45-
struct StatusesReturn {
46-
string status;
47-
uint256 buyOrderId;
48-
}
49-
5038
function getERC721BuyOrderStatuses(uint256[] calldata _buyOrderIds) external view returns (StatusesReturn[] memory statuses_) {
5139
uint256 length = _buyOrderIds.length;
5240
statuses_ = new StatusesReturn[](length);
@@ -92,71 +80,17 @@ contract ERC721BuyOrderFacet is Modifiers {
9280
uint256 _duration,
9381
bool[] calldata _validationOptions // 0: BRS, 1: GHST, 2: skill points
9482
) external whenNotPaused {
95-
require(_priceInWei >= 1e18, "ERC721BuyOrder: price should be 1 GHST or larger");
96-
9783
address sender = LibMeta.msgSender();
9884
uint256 ghstBalance = IERC20(s.ghstContract).balanceOf(sender);
9985
require(ghstBalance >= _priceInWei, "ERC721BuyOrder: Not enough GHST!");
10086

101-
// Aavegotchi-specific validation
102-
if (_erc721TokenAddress == address(this)) {
103-
AavegotchiInfo memory aavegotchiInfo = LibAavegotchi.getAavegotchi(_erc721TokenId);
104-
uint256 category = aavegotchiInfo.status;
105-
require(category == _category, "ERC721BuyOrder: Category mismatch");
106-
require(category != LibAavegotchi.STATUS_VRF_PENDING, "ERC721BuyOrder: Cannot buy a portal that is pending VRF");
107-
108-
if (category == LibAavegotchi.STATUS_AAVEGOTCHI) {
109-
require(_validationOptions.length == 3, "ERC721BuyOrder: Not enough validation options for aavegotchi");
110-
}
111-
}
112-
113-
require(sender != IERC721(_erc721TokenAddress).ownerOf(_erc721TokenId), "ERC721BuyOrder: Owner can't be buyer");
114-
115-
uint256 oldBuyOrderId = s.buyerToBuyOrderId[_erc721TokenAddress][_erc721TokenId][sender];
116-
if (oldBuyOrderId != 0) {
117-
ERC721BuyOrder memory erc721BuyOrder = s.erc721BuyOrders[oldBuyOrderId];
118-
require(erc721BuyOrder.timeCreated != 0, "ERC721BuyOrder: ERC721 buyOrder does not exist");
119-
require(erc721BuyOrder.cancelled == false && erc721BuyOrder.timePurchased == 0, "ERC721BuyOrder: Already processed");
120-
if ((erc721BuyOrder.duration == 0) || (erc721BuyOrder.timeCreated + erc721BuyOrder.duration >= block.timestamp)) {
121-
LibBuyOrder.cancelERC721BuyOrder(oldBuyOrderId);
122-
emit ERC721BuyOrderCanceled(oldBuyOrderId, block.timestamp);
123-
}
124-
}
87+
uint256 totalCost = LibBuyOrder.validateERC721Params(_erc721TokenAddress, _erc721TokenId, _category, _priceInWei, _validationOptions);
12588

12689
// Transfer GHST
127-
LibERC20.transferFrom(s.ghstContract, sender, address(this), _priceInWei);
90+
LibERC20.transferFrom(s.ghstContract, sender, address(this), totalCost);
12891

12992
// Place new buy order
130-
s.nextERC721BuyOrderId++;
131-
uint256 buyOrderId = s.nextERC721BuyOrderId;
132-
133-
s.buyerToBuyOrderId[_erc721TokenAddress][_erc721TokenId][sender] = buyOrderId;
134-
135-
bytes32 _validationHash = LibBuyOrder.generateValidationHash(_erc721TokenAddress, _erc721TokenId, _validationOptions);
136-
s.erc721BuyOrders[buyOrderId] = ERC721BuyOrder({
137-
buyOrderId: buyOrderId,
138-
buyer: sender,
139-
erc721TokenAddress: _erc721TokenAddress,
140-
erc721TokenId: _erc721TokenId,
141-
priceInWei: _priceInWei,
142-
validationHash: _validationHash,
143-
timeCreated: block.timestamp,
144-
timePurchased: 0,
145-
duration: _duration,
146-
cancelled: false,
147-
validationOptions: _validationOptions
148-
});
149-
emit ERC721BuyOrderAdded(
150-
buyOrderId,
151-
sender,
152-
_erc721TokenAddress,
153-
_erc721TokenId,
154-
_category,
155-
_priceInWei,
156-
_duration,
157-
_validationHash,
158-
block.timestamp
159-
);
93+
LibBuyOrder._placeERC721BuyOrder(_erc721TokenAddress, _erc721TokenId, _category, _priceInWei, _duration, _validationOptions);
16094
}
16195

16296
function cancelERC721BuyOrder(uint256 _buyOrderId) external whenNotPaused {
@@ -174,7 +108,7 @@ contract ERC721BuyOrderFacet is Modifiers {
174108
}
175109

176110
LibBuyOrder.cancelERC721BuyOrder(_buyOrderId);
177-
emit ERC721BuyOrderCanceled(_buyOrderId, block.timestamp);
111+
emit LibBuyOrder.ERC721BuyOrderCanceled(_buyOrderId, block.timestamp);
178112
}
179113

180114
function executeERC721BuyOrder(

contracts/Aavegotchi/facets/ERC721MarketplaceSwapFacet.sol

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
// SPDX-License-Identifier: MIT
22
pragma solidity 0.8.1;
33

4-
import {LibAppStorage, AppStorage} from "../libraries/LibAppStorage.sol";
54
import {LibERC721Marketplace} from "../libraries/LibERC721Marketplace.sol";
65
import {LibTokenSwap} from "../libraries/LibTokenSwap.sol";
7-
import {IERC20} from "../../shared/interfaces/IERC20.sol";
86
import {Modifiers} from "../libraries/LibAppStorage.sol";
97

108
contract ERC721MarketplaceSwapFacet is Modifiers {
@@ -45,9 +43,6 @@ contract ERC721MarketplaceSwapFacet is Modifiers {
4543
LibTokenSwap.validateSwapParams(tokenIn, swapAmount, minGhstOut, swapDeadline);
4644
require(minGhstOut >= priceInWei, "ERC721MarketplaceSwap: minGhstOut must cover price");
4745

48-
AppStorage storage s = LibAppStorage.diamondStorage();
49-
uint256 initialBalance = IERC20(s.ghstContract).balanceOf(address(this));
50-
5146
// Perform token swap to GHST
5247
uint256 ghstReceived = LibTokenSwap.swapForGHST(tokenIn, swapAmount, minGhstOut, swapDeadline, address(this));
5348

@@ -59,7 +54,7 @@ contract ERC721MarketplaceSwapFacet is Modifiers {
5954
LibERC721Marketplace.executeERC721Listing(listingId, contractAddress, priceInWei, tokenId, recipient, address(this));
6055

6156
// Refund any excess GHST to the recipient using shared library
62-
LibTokenSwap.refundExcessGHST(recipient, initialBalance);
57+
LibTokenSwap.refundExcessGHST(recipient, ghstReceived, priceInWei);
6358

6459
emit SwapAndPurchase(recipient, tokenIn, swapAmount, ghstReceived, listingId, tokenId, contractAddress);
6560
}

0 commit comments

Comments
 (0)