-
Notifications
You must be signed in to change notification settings - Fork 22
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
07b2cd2
commit ca995d7
Showing
6 changed files
with
385 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,6 +2,8 @@ | |
cache/ | ||
out/ | ||
|
||
.vscode | ||
|
||
# Ignores development broadcast logs | ||
/broadcast | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
// SPDX-License-Identifier: MIT | ||
|
||
pragma solidity ^0.8.20; | ||
|
||
import {WellUpgradeable} from "src/WellUpgradeable.sol"; | ||
|
||
// this needs to be here for upgrade checks | ||
/// @custom:oz-upgrades-from WellUpgradeable | ||
contract MockWellUpgradeable is WellUpgradeable { | ||
|
||
function getVersion(uint256 i) external pure returns (uint256) { | ||
return i; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
// SPDX-License-Identifier: MIT | ||
|
||
pragma solidity ^0.8.20; | ||
|
||
import {Well} from "src/Well.sol"; | ||
import {UUPSUpgradeable} from "ozu/proxy/utils/UUPSUpgradeable.sol"; | ||
import {OwnableUpgradeable} from "ozu/access/OwnableUpgradeable.sol"; | ||
import {IERC20, SafeERC20} from "oz/token/ERC20/utils/SafeERC20.sol"; | ||
|
||
|
||
/** | ||
* @title Well | ||
* @author Publius, Silo Chad, Brean, Deadmanwalking | ||
* @dev A Well is a constant function AMM allowing the provisioning of liquidity | ||
* into a single pooled on-chain liquidity position. | ||
* | ||
* Rebasing Tokens: | ||
* - Positive rebasing tokens are supported by Wells, but any tokens recieved from a | ||
* rebase will not be rewarded to LP holders and instead can be extracted by anyone | ||
* using `skim`, `sync` or `shift`. | ||
* - Negative rebasing tokens should not be used in Well as the effect of a negative | ||
* rebase will be realized by users interacting with the Well, not LP token holders. | ||
* | ||
* Fee on Tranfer (FoT) Tokens: | ||
* - When transferring fee on transfer tokens to a Well (swapping from or adding liquidity), | ||
* use `swapFromFeeOnTrasfer` or `addLiquidityFeeOnTransfer`. `swapTo` does not support | ||
* fee on transfer tokens (See {swapTo}). | ||
* - When recieving fee on transfer tokens from a Well (swapping to and removing liquidity), | ||
* INCLUDE the fee that is taken on transfer when calculating amount out values. | ||
*/ | ||
contract WellUpgradeable is Well, UUPSUpgradeable, OwnableUpgradeable { | ||
|
||
/** | ||
* Perform an upgrade of an ERC1967Proxy, when this contract. | ||
* is set as the implementation behind such a proxy. | ||
* The _authorizeUpgrade function must be overridden. | ||
* to include access restriction to the upgrade mechanism. | ||
*/ | ||
function _authorizeUpgrade(address) internal override onlyOwner {} | ||
|
||
function init(string memory _name, string memory _symbol, address owner) external initializer { | ||
// owner of well param as the aquifier address will be the owner initially | ||
// ownable init transfers ownership to msg.sender | ||
__ERC20Permit_init(_name); | ||
__ERC20_init(_name, _symbol); | ||
__ReentrancyGuard_init(); | ||
__UUPSUpgradeable_init(); | ||
// first time this is called the owner will be the msg.sender | ||
// which is the aquifer that bore the well | ||
__Ownable_init(); | ||
// then ownership can be transfered to the wanted address | ||
// note: to init owner with __Ownable_init(ownerAddress); we would need to adjust the lib code | ||
transferOwnership(owner); | ||
|
||
IERC20[] memory _tokens = tokens(); | ||
uint256 tokensLength = _tokens.length; | ||
for (uint256 i; i < tokensLength - 1; ++i) { | ||
for (uint256 j = i + 1; j < tokensLength; ++j) { | ||
if (_tokens[i] == _tokens[j]) { | ||
revert DuplicateTokens(_tokens[i]); | ||
} | ||
} | ||
} | ||
} | ||
|
||
function getVersion() external virtual pure returns (uint256) { | ||
return 1; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
// SPDX-License-Identifier: MIT | ||
// forgefmt: disable-start | ||
|
||
pragma solidity ^0.8.20; | ||
|
||
import {LibContractInfo} from "src/libraries/LibContractInfo.sol"; | ||
import {Call, IERC20} from "src/Well.sol"; | ||
|
||
library LibWellUpgradeableConstructor { | ||
|
||
/** | ||
* @notice Encode the Well's immutable data and init data with an owner. | ||
*/ | ||
function encodeWellDeploymentData( | ||
address _aquifer, | ||
IERC20[] memory _tokens, | ||
Call memory _wellFunction, | ||
Call[] memory _pumps, | ||
address owner | ||
) internal view returns (bytes memory immutableData, bytes memory initData) { | ||
immutableData = encodeWellImmutableData(_aquifer, _tokens, _wellFunction, _pumps); | ||
initData = encodeWellInitFunctionCall(_tokens, _wellFunction, owner); | ||
} | ||
|
||
/** | ||
* @notice Encode the Well's immutable data. | ||
* @param _aquifer The address of the Aquifer which will deploy this Well. | ||
* @param _tokens A list of ERC20 tokens supported by the Well. | ||
* @param _wellFunction A single Call struct representing a call to the Well Function. | ||
* @param _pumps An array of Call structs representings calls to Pumps. | ||
* @dev `immutableData` is tightly packed, however since `_tokens` itself is | ||
* an array, each address in the array will be padded up to 32 bytes. | ||
* | ||
* Arbitrary-length bytes are applied to the end of the encoded bytes array | ||
* for easy reading of statically-sized data. | ||
* | ||
*/ | ||
function encodeWellImmutableData( | ||
address _aquifer, | ||
IERC20[] memory _tokens, | ||
Call memory _wellFunction, | ||
Call[] memory _pumps | ||
) internal pure returns (bytes memory immutableData) { | ||
|
||
immutableData = abi.encodePacked( | ||
_aquifer, // aquifer address | ||
_tokens.length, // number of tokens | ||
_wellFunction.target, // well function address | ||
_wellFunction.data.length, // well function data length | ||
_pumps.length, // number of pumps | ||
_tokens, // tokens array | ||
_wellFunction.data // well function data (bytes) | ||
); | ||
for (uint256 i; i < _pumps.length; ++i) { | ||
immutableData = abi.encodePacked( | ||
immutableData, // previously packed pumps | ||
_pumps[i].target, // pump address | ||
_pumps[i].data.length, // pump data length | ||
_pumps[i].data // pump data (bytes) | ||
); | ||
} | ||
} | ||
|
||
function encodeWellInitFunctionCall( | ||
IERC20[] memory _tokens, | ||
Call memory _wellFunction, | ||
address owner | ||
) public view returns (bytes memory initFunctionCall) { | ||
string memory name = LibContractInfo.getSymbol(address(_tokens[0])); | ||
string memory symbol = name; | ||
for (uint256 i = 1; i < _tokens.length; ++i) { | ||
name = string.concat(name, ":", LibContractInfo.getSymbol(address(_tokens[i]))); | ||
symbol = string.concat(symbol, LibContractInfo.getSymbol(address(_tokens[i]))); | ||
} | ||
name = string.concat(name, " ", LibContractInfo.getName(_wellFunction.target), " Well"); | ||
symbol = string.concat(symbol, LibContractInfo.getSymbol(_wellFunction.target), "w"); | ||
|
||
// See {Well.init}. | ||
initFunctionCall = abi.encodeWithSignature("init(string,string,address)", name, symbol, owner); | ||
} | ||
|
||
/** | ||
* @notice Encode a Call struct representing an arbitrary call to `target` with additional data `data`. | ||
*/ | ||
function encodeCall(address target, bytes memory data) public pure returns (Call memory) { | ||
return Call(target, data); | ||
} | ||
} |
Oops, something went wrong.