Skip to content

Instantly share code, notes, and snippets.

@antoncoding
Last active July 8, 2020 12:48
Show Gist options
  • Save antoncoding/71380ffbe4e35533e2d9c7376d9f6423 to your computer and use it in GitHub Desktop.
Save antoncoding/71380ffbe4e35533e2d9c7376d9f6423 to your computer and use it in GitHub Desktop.
// SPDX-License-Identifier: UNLICENSED
pragma solidity =0.6.10;
pragma experimental ABIEncoderV2;
library Vaults {
struct Vault {
address[] collateralAssets;
uint256[] collateralAmounts;
address[] longAssets;
uint256[] longAmounts;
}
}
library Actions {
// ============ Enums ============
enum ActionType {
AddCollateral,
RemoveCollateral,
AddShort,
RemoveShort,
AddLong,
RemoveLong
}
// ============ Structs ============
/*
* Arguments that are passed to Solo in an ordered list as part of a single operation.
* Each ActionArgs has an actionType which specifies which action struct that this data will be
* parsed into before being processed.
*/
struct ActionArgs {
ActionType actionType;
uint256 amount;
address asset;
uint256 index;
}
// ============ Action Types ============
struct AddCollateralArgs {
uint256 amount;
address asset;
uint256 index;
}
struct RemoveCollateralArgs {
uint256 amount;
address asset;
uint256 index;
}
struct AddLongArgs {
uint256 amount;
address asset;
uint256 index;
}
struct RemoveLongArgs {
uint256 amount;
address asset;
uint256 index;
}
// ============= Parsing Functions =============
function parseAddCollateral(
ActionArgs memory args
)
internal
pure
returns (AddCollateralArgs memory)
{
assert(args.actionType == ActionType.AddCollateral);
return AddCollateralArgs({
amount: args.amount,
asset: args.asset,
index: args.index
});
}
function parseRemoveCollateral(
ActionArgs memory args
)
internal
pure
returns (RemoveCollateralArgs memory)
{
assert(args.actionType == ActionType.RemoveCollateral);
return RemoveCollateralArgs({
amount: args.amount,
asset: args.asset,
index: args.index
});
}
function parseAddLong(
ActionArgs memory args
)
internal
pure
returns (AddLongArgs memory)
{
assert(args.actionType == ActionType.AddLong);
return AddLongArgs({
amount: args.amount,
asset: args.asset,
index: args.index
});
}
function parseRemoveLong(
ActionArgs memory args
)
internal
pure
returns (RemoveLongArgs memory)
{
assert(args.actionType == ActionType.RemoveLong);
return RemoveLongArgs({
amount: args.amount,
asset: args.asset,
index: args.index
});
}
}
contract Controller {
struct MarginAccount {
Vaults.Vault[] vaults;
}
mapping(address => MarginAccount) private account;
function operate(address user, uint256 vaultId, Actions.ActionArgs[] memory actions) external {
Vaults.Vault storage vault = account[user].vaults[vaultId];
_runActions(vault, actions);
// _checkRequirement(vault)
}
function _runActions(
Vaults.Vault storage vault,
Actions.ActionArgs[] memory actions
)
private
{
for (uint256 i = 0; i < actions.length; i++) {
Actions.ActionArgs memory action = actions[i];
Actions.ActionType actionType = action.actionType;
if (actionType == Actions.ActionType.AddCollateral) {
_addCollateral(vault, Actions.parseAddCollateral(action));
}
else if (actionType == Actions.ActionType.RemoveCollateral) {
_removeCollateral(
vault,
Actions.parseRemoveCollateral(action)
);
}
}
}
function _addCollateral(Vaults.Vault storage vault, Actions.AddCollateralArgs memory args) private {
vault.collateralAssets[args.index] = args.asset;
vault.collateralAmounts[args.index] -= args.amount;
}
function _removeCollateral(Vaults.Vault storage vault, Actions.RemoveCollateralArgs memory args) private {
require(vault.collateralAssets[args.index] == args.asset);
require(vault.collateralAmounts[args.index] >= args.amount);
vault.collateralAmounts[args.index] -= args.amount;
// transferFrom()
}
function _addLong(Vaults.Vault storage vault, Actions.AddLongArgs memory args) private {
}
function _removeLong(Vaults.Vault storage vault, Actions.RemoveLongArgs memory args) private {
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment