forked from sudoswap/lssvm
-
Notifications
You must be signed in to change notification settings - Fork 0
/
LSSVMPairETH.sol
140 lines (122 loc) · 4.56 KB
/
LSSVMPairETH.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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
// SPDX-License-Identifier: AGPL-3.0
pragma solidity ^0.8.0;
import {ERC20} from "solmate/tokens/ERC20.sol";
import {IERC721} from "@openzeppelin/contracts/token/ERC721/IERC721.sol";
import {SafeTransferLib} from "solmate/utils/SafeTransferLib.sol";
import {LSSVMPair} from "./LSSVMPair.sol";
import {ILSSVMPairFactoryLike} from "./ILSSVMPairFactoryLike.sol";
import {ICurve} from "./bonding-curves/ICurve.sol";
/**
@title An NFT/Token pair where the token is ETH
@author boredGenius and 0xmons
*/
abstract contract LSSVMPairETH is LSSVMPair {
using SafeTransferLib for address payable;
using SafeTransferLib for ERC20;
uint256 internal constant IMMUTABLE_PARAMS_LENGTH = 61;
/// @inheritdoc LSSVMPair
function _pullTokenInputAndPayProtocolFee(
uint256 inputAmount,
bool, /*isRouter*/
address, /*routerCaller*/
ILSSVMPairFactoryLike _factory,
uint256 protocolFee
) internal override {
require(msg.value >= inputAmount, "Sent too little ETH");
// Transfer inputAmount ETH to assetRecipient if it's been set
address payable _assetRecipient = getAssetRecipient();
if (_assetRecipient != address(this)) {
_assetRecipient.safeTransferETH(inputAmount - protocolFee);
}
// Take protocol fee
if (protocolFee > 0) {
// Round down to the actual ETH balance if there are numerical stability issues with the bonding curve calculations
if (protocolFee > address(this).balance) {
protocolFee = address(this).balance;
}
if (protocolFee > 0) {
payable(address(_factory)).safeTransferETH(protocolFee);
}
}
}
/// @inheritdoc LSSVMPair
function _refundTokenToSender(uint256 inputAmount) internal override {
// Give excess ETH back to caller
if (msg.value > inputAmount) {
payable(msg.sender).safeTransferETH(msg.value - inputAmount);
}
}
/// @inheritdoc LSSVMPair
function _payProtocolFeeFromPair(
ILSSVMPairFactoryLike _factory,
uint256 protocolFee
) internal override {
// Take protocol fee
if (protocolFee > 0) {
// Round down to the actual ETH balance if there are numerical stability issues with the bonding curve calculations
if (protocolFee > address(this).balance) {
protocolFee = address(this).balance;
}
if (protocolFee > 0) {
payable(address(_factory)).safeTransferETH(protocolFee);
}
}
}
/// @inheritdoc LSSVMPair
function _sendTokenOutput(
address payable tokenRecipient,
uint256 outputAmount
) internal override {
// Send ETH to caller
if (outputAmount > 0) {
tokenRecipient.safeTransferETH(outputAmount);
}
}
/// @inheritdoc LSSVMPair
// @dev see LSSVMPairCloner for params length calculation
function _immutableParamsLength() internal pure override returns (uint256) {
return IMMUTABLE_PARAMS_LENGTH;
}
/**
@notice Withdraws all token owned by the pair to the owner address.
@dev Only callable by the owner.
*/
function withdrawAllETH() external onlyOwner {
withdrawETH(address(this).balance);
}
/**
@notice Withdraws a specified amount of token owned by the pair to the owner address.
@dev Only callable by the owner.
@param amount The amount of token to send to the owner. If the pair's balance is less than
this value, the transaction will be reverted.
*/
function withdrawETH(uint256 amount) public onlyOwner {
payable(owner()).safeTransferETH(amount);
// emit event since ETH is the pair token
emit TokenWithdrawal(amount);
}
/// @inheritdoc LSSVMPair
function withdrawERC20(ERC20 a, uint256 amount)
external
override
onlyOwner
{
a.safeTransfer(msg.sender, amount);
}
/**
@dev All ETH transfers into the pair are accepted. This is the main method
for the owner to top up the pair's token reserves.
*/
receive() external payable {
emit TokenDeposit(msg.value);
}
/**
@dev All ETH transfers into the pair are accepted. This is the main method
for the owner to top up the pair's token reserves.
*/
fallback() external payable {
// Only allow calls without function selector
require (msg.data.length == _immutableParamsLength());
emit TokenDeposit(msg.value);
}
}