TradeModule
About
Stats
Public Functions
3
Event Types
1
Code Size
89,860 bytes
Library Use
Uses SafeCast for int256.
Uses SafeMath for uint256.
Uses Invoke for ISetToken.
Uses Position for ISetToken.
Uses PreciseUnitMath for uint256.
Structs (1) keyboard_arrow_up
TradeInfo Struct
Members
setToken |
ISetToken help
|
exchangeAdapter |
IExchangeAdapter help
|
sendToken |
address help
|
receiveToken |
address help
|
setTotalSupply |
uint256 help
|
totalSendQuantity |
uint256 help
|
totalMinReceiveQuantity |
uint256 help
|
preTradeSendTokenBalance |
uint256 help
|
preTradeReceiveTokenBalance |
uint256 help
|
Functions
initialize keyboard_arrow_up
Modifiers help
onlyValidAndPendingSet checks for the following:
null
onlySetManager checks for the following:
null
Source Code
function initialize(ISetToken _setToken)
external
onlyValidAndPendingSet(_setToken)
onlySetManager(_setToken, msg.sender)
{
_setToken.initializeModule();
}
trade keyboard_arrow_up
Parameters help
Modifiers help
Requirements help
Source Code
function trade(
ISetToken _setToken,
string memory _exchangeName,
address _sendToken,
uint256 _sendQuantity,
address _receiveToken,
uint256 _minReceiveQuantity,
bytes memory _data
) external nonReentrant onlyManagerAndValidSet(_setToken) {
TradeInfo memory tradeInfo = _createTradeInfo(
_setToken,
_exchangeName,
_sendToken,
_receiveToken,
_sendQuantity,
_minReceiveQuantity
);
_validatePreTradeData(tradeInfo, _sendQuantity);
_executeTrade(tradeInfo, _data);
uint256 exchangedQuantity = _validatePostTrade(tradeInfo);
uint256 protocolFee = _accrueProtocolFee(tradeInfo, exchangedQuantity);
(uint256 netSendAmount, uint256 netReceiveAmount) = _updateSetTokenPositions(
tradeInfo
);
emit ComponentExchanged(
_setToken,
_sendToken,
_receiveToken,
tradeInfo.exchangeAdapter,
netSendAmount,
netReceiveAmount,
protocolFee
);
}
Internal Functions
Internal functions are parts of the contract that can't be used directly, but instead are used by the public functions listed above.
internal TradeModule._createTradeInfo keyboard_arrow_up
Parameters help
Source Code
function _createTradeInfo(
ISetToken _setToken,
string memory _exchangeName,
address _sendToken,
address _receiveToken,
uint256 _sendQuantity,
uint256 _minReceiveQuantity
) internal view returns (TradeInfo memory) {
TradeInfo memory tradeInfo;
tradeInfo.setToken = _setToken;
tradeInfo.exchangeAdapter = IExchangeAdapter(
getAndValidateAdapter(_exchangeName)
);
tradeInfo.sendToken = _sendToken;
tradeInfo.receiveToken = _receiveToken;
tradeInfo.setTotalSupply = _setToken.totalSupply();
tradeInfo.totalSendQuantity = Position.getDefaultTotalNotional(
tradeInfo.setTotalSupply,
_sendQuantity
);
tradeInfo.totalMinReceiveQuantity = Position.getDefaultTotalNotional(
tradeInfo.setTotalSupply,
_minReceiveQuantity
);
tradeInfo.preTradeSendTokenBalance = IERC20(_sendToken).balanceOf(
address(_setToken)
);
tradeInfo.preTradeReceiveTokenBalance = IERC20(_receiveToken).balanceOf(
address(_setToken)
);
return tradeInfo;
}
internal TradeModule._validatePreTradeData keyboard_arrow_up
Requirements help
Source Code
function _validatePreTradeData(
TradeInfo memory _tradeInfo,
uint256 _sendQuantity
) internal view {
require(_tradeInfo.totalSendQuantity > 0, "Token to sell must be nonzero");
require(
_tradeInfo.setToken.hasSufficientDefaultUnits(
_tradeInfo.sendToken,
_sendQuantity
),
"Unit cant be greater than existing"
);
}
internal TradeModule._executeTrade keyboard_arrow_up
Source Code
function _executeTrade(TradeInfo memory _tradeInfo, bytes memory _data)
internal
{
// Get spender address from exchange adapter and invoke approve for exact amount on SetToken
_tradeInfo.setToken.invokeApprove(
_tradeInfo.sendToken,
_tradeInfo.exchangeAdapter.getSpender(),
_tradeInfo.totalSendQuantity
);
(
address targetExchange,
uint256 callValue,
bytes memory methodData
) = _tradeInfo.exchangeAdapter.getTradeCalldata(
_tradeInfo.sendToken,
_tradeInfo.receiveToken,
address(_tradeInfo.setToken),
_tradeInfo.totalSendQuantity,
_tradeInfo.totalMinReceiveQuantity,
_data
);
_tradeInfo.setToken.invoke(targetExchange, callValue, methodData);
}
internal TradeModule._validatePostTrade keyboard_arrow_up
Requirements help
Source Code
function _validatePostTrade(TradeInfo memory _tradeInfo)
internal
view
returns (uint256)
{
uint256 exchangedQuantity = IERC20(_tradeInfo.receiveToken)
.balanceOf(address(_tradeInfo.setToken))
.sub(_tradeInfo.preTradeReceiveTokenBalance);
require(
exchangedQuantity >= _tradeInfo.totalMinReceiveQuantity,
"Slippage greater than allowed"
);
return exchangedQuantity;
}
internal TradeModule._accrueProtocolFee keyboard_arrow_up
Source Code
function _accrueProtocolFee(
TradeInfo memory _tradeInfo,
uint256 _exchangedQuantity
) internal returns (uint256) {
uint256 protocolFeeTotal = getModuleFee(
TRADE_MODULE_PROTOCOL_FEE_INDEX,
_exchangedQuantity
);
payProtocolFeeFromSetToken(
_tradeInfo.setToken,
_tradeInfo.receiveToken,
protocolFeeTotal
);
return protocolFeeTotal;
}
internal TradeModule._updateSetTokenPositions keyboard_arrow_up
Source Code
function _updateSetTokenPositions(TradeInfo memory _tradeInfo)
internal
returns (uint256, uint256)
{
(uint256 currentSendTokenBalance, , ) = _tradeInfo
.setToken
.calculateAndEditDefaultPosition(
_tradeInfo.sendToken,
_tradeInfo.setTotalSupply,
_tradeInfo.preTradeSendTokenBalance
);
(uint256 currentReceiveTokenBalance, , ) = _tradeInfo
.setToken
.calculateAndEditDefaultPosition(
_tradeInfo.receiveToken,
_tradeInfo.setTotalSupply,
_tradeInfo.preTradeReceiveTokenBalance
);
return (
_tradeInfo.preTradeSendTokenBalance.sub(currentSendTokenBalance),
currentReceiveTokenBalance.sub(_tradeInfo.preTradeReceiveTokenBalance)
);
}
internal ModuleBase.transferFrom keyboard_arrow_up
Parameters help
Source Code
function transferFrom(
IERC20 _token,
address _from,
address _to,
uint256 _quantity
) internal {
ExplicitERC20.transferFrom(_token, _from, _to, _quantity);
}
internal ModuleBase.getAndValidateAdapter keyboard_arrow_up
Source Code
function getAndValidateAdapter(string memory _integrationName)
internal
view
returns (address)
{
bytes32 integrationHash = getNameHash(_integrationName);
return getAndValidateAdapterWithHash(integrationHash);
}
internal ModuleBase.getAndValidateAdapterWithHash keyboard_arrow_up
Source Code
function getAndValidateAdapterWithHash(bytes32 _integrationHash)
internal
view
returns (address)
{
address adapter = controller
.getIntegrationRegistry()
.getIntegrationAdapterWithHash(address(this), _integrationHash);
require(adapter != address(0), "Must be valid adapter");
return adapter;
}
internal ModuleBase.getModuleFee keyboard_arrow_up
Source Code
function getModuleFee(uint256 _feeIndex, uint256 _quantity)
internal
view
returns (uint256)
{
uint256 feePercentage = controller.getModuleFee(address(this), _feeIndex);
return _quantity.preciseMul(feePercentage);
}
internal ModuleBase.payProtocolFeeFromSetToken keyboard_arrow_up
Source Code
function payProtocolFeeFromSetToken(
ISetToken _setToken,
address _token,
uint256 _feeQuantity
) internal {
if (_feeQuantity > 0) {
_setToken.strictInvokeTransfer(
_token,
controller.feeRecipient(),
_feeQuantity
);
}
}
internal ModuleBase.isSetPendingInitialization keyboard_arrow_up
internal ModuleBase.isSetManager keyboard_arrow_up
internal ModuleBase.isSetValidAndInitialized keyboard_arrow_up
Source Code
function isSetValidAndInitialized(ISetToken _setToken)
internal
view
returns (bool)
{
return
controller.isSet(address(_setToken)) &&
_setToken.isInitializedModule(address(this));
}