-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathSimpleOTC.sol
95 lines (81 loc) · 3.56 KB
/
SimpleOTC.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
//SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;
import {CurioTreaty} from "contracts/standards/CurioTreaty.sol";
import {CurioERC20} from "contracts/standards/CurioERC20.sol";
import {GetterFacet} from "contracts/facets/GetterFacet.sol";
struct Order {
string sellTokenName;
uint256 sellAmount;
string buyTokenName;
uint256 buyAmount;
uint256 createdAt;
}
/// @notice Each player has one active sell order at most
contract SimpleOTC is CurioTreaty {
mapping(address => Order) public sellerToOrder;
Order public emptyOrder;
function init(address _diamond) public override {
super.init(_diamond);
emptyOrder = Order({sellTokenName: "", sellAmount: 0, buyTokenName: "", buyAmount: 0, createdAt: 0});
}
// ----------------------------------------------------------
// Owner functions
// ----------------------------------------------------------
function name() external pure override returns (string memory) {
return "Simple OTC Trading Agreement";
}
function description() external pure override returns (string memory) {
return "OTC Trading between players";
}
/**
* @dev Create an order. Must be called by a nation.
* @param _sellTokenName name of the token to sell
* @param _sellAmount amount of the token to sell
* @param _buyTokenName name of the token to buy
* @param _buyAmount amount of the token to buy
*/
function createOrder(
string memory _sellTokenName,
uint256 _sellAmount,
string memory _buyTokenName,
uint256 _buyAmount
) public {
require(sellerToOrder[msg.sender].sellAmount == 0, "OTC: You have an existing order");
require(_sellAmount > 0 && _buyAmount > 0, "OTC: Amounts must be greater than 0");
sellerToOrder[msg.sender] = Order({
sellTokenName: _sellTokenName, // FORMATTING: DO NOT REMOVE THIS COMMENT
sellAmount: _sellAmount,
buyTokenName: _buyTokenName,
buyAmount: _buyAmount,
createdAt: block.timestamp
});
}
/**
* @dev Cancel an order. Must be called by a nation.
*/
function cancelOrder() public {
require(sellerToOrder[msg.sender].sellAmount > 0, "OTC: You have no existing order");
require(block.timestamp > sellerToOrder[msg.sender].createdAt + 120, "OTC: Can only cancel after 2 minutes");
// Set order to empty
sellerToOrder[msg.sender] = emptyOrder;
}
/**
* @dev Take an order and complete the transfers. Must be called by a nation.
* @param _seller address of the seller
*/
function takeOrder(address _seller) public {
GetterFacet getter = GetterFacet(diamond);
require(sellerToOrder[_seller].sellAmount > 0, "OTC: Seller has no existing order");
// Fetch token pair
Order memory targetOrder = sellerToOrder[_seller];
CurioERC20 sellToken = getter.getTokenContract(targetOrder.sellTokenName);
CurioERC20 buyToken = getter.getTokenContract(targetOrder.buyTokenName);
// Transfer tokens
address buyerCapitalAddress = getter.getAddress(getter.getCapital(getter.getEntityByAddress(msg.sender)));
address sellerCapitalAddress = getter.getAddress(getter.getCapital(getter.getEntityByAddress(_seller)));
sellToken.transferFrom(sellerCapitalAddress, buyerCapitalAddress, targetOrder.sellAmount);
buyToken.transferFrom(buyerCapitalAddress, sellerCapitalAddress, targetOrder.buyAmount);
// Remove order
sellerToOrder[_seller] = emptyOrder;
}
}