Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 25 additions & 10 deletions contracts/Auth2.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,38 +7,53 @@ pragma solidity 0.7.6;

import "./VaultParameters.sol";


/**
* @title Auth2
* @dev Manages USDP's system access
* @dev copy of Auth from VaultParameters.sol but with immutable vaultParameters for saving gas
**/
* @notice Auth2 is a contract that manages USDP's system access with immutable vaultParameters for gas optimization.
* @dev Inherits VaultParameters contract's properties for access control.
* @dev Copy of Auth from VaultParameters.sol but with immutable vaultParameters for saving gas
*/
contract Auth2 {

// address of the the contract with vault parameters
/**
* @notice The VaultParameters contract which holds system parameters.
* @dev Immutable to save gas, as it's set only once upon construction and cannot be changed afterwards.
*/
VaultParameters public immutable vaultParameters;

/**
* @notice Constructs the Auth2 contract.
* @param _parameters The address of the VaultParameters contract.
*/
constructor(address _parameters) {
require(_parameters != address(0), "Unit Protocol: ZERO_ADDRESS");

vaultParameters = VaultParameters(_parameters);
}

// ensures tx's sender is a manager
/**
* @notice Ensures the transaction's sender is a manager.
* @dev Modifier that throws if the sender is not a manager.
*/
modifier onlyManager() {
require(vaultParameters.isManager(msg.sender), "Unit Protocol: AUTH_FAILED");
_;
}

// ensures tx's sender is able to modify the Vault
/**
* @notice Ensures the transaction's sender has access to modify the Vault.
* @dev Modifier that throws if the sender cannot modify the Vault.
*/
modifier hasVaultAccess() {
require(vaultParameters.canModifyVault(msg.sender), "Unit Protocol: AUTH_FAILED");
_;
}

// ensures tx's sender is the Vault
/**
* @notice Ensures the transaction's sender is the Vault itself.
* @dev Modifier that throws if the sender is not the Vault.
*/
modifier onlyVault() {
require(msg.sender == vaultParameters.vault(), "Unit Protocol: AUTH_FAILED");
_;
}
}
}
71 changes: 69 additions & 2 deletions contracts/CDPRegistry.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@ pragma experimental ABIEncoderV2;
import "./interfaces/IVault.sol";
import "./interfaces/ICollateralRegistry.sol";


/**
* @title CDPRegistry
* @dev Contract to manage a registry of collateralized debt positions (CDPs) for the Unit Protocol.
*/
contract CDPRegistry {

struct CDP {
Expand All @@ -26,12 +29,22 @@ contract CDPRegistry {
event Added(address indexed asset, address indexed owner);
event Removed(address indexed asset, address indexed owner);

/**
* @dev Constructs the CDPRegistry contract.
* @param _vault Address of the IVault contract.
* @param _collateralRegistry Address of the ICollateralRegistry contract.
*/
constructor (address _vault, address _collateralRegistry) {
require(_vault != address(0) && _collateralRegistry != address(0), "Unit Protocol: ZERO_ADDRESS");
vault = IVault(_vault);
cr = ICollateralRegistry(_collateralRegistry);
}

/**
* @dev Updates the CDP registry for a given asset and owner.
* @param asset Address of the asset.
* @param owner Address of the owner.
*/
function checkpoint(address asset, address owner) public {
require(asset != address(0) && owner != address(0), "Unit Protocol: ZERO_ADDRESS");

Expand All @@ -45,28 +58,55 @@ contract CDPRegistry {
}
}

/**
* @dev Updates the CDP registry for a given asset and multiple owners.
* @param asset Address of the asset.
* @param owners Array of owner addresses.
*/
function batchCheckpointForAsset(address asset, address[] calldata owners) external {
for (uint i = 0; i < owners.length; i++) {
checkpoint(asset, owners[i]);
}
}

/**
* @dev Updates the CDP registry for multiple assets and owners.
* @param assets Array of asset addresses.
* @param owners Array of owner addresses.
*/
function batchCheckpoint(address[] calldata assets, address[] calldata owners) external {
require(assets.length == owners.length, "Unit Protocol: ARGUMENTS_LENGTH_MISMATCH");
for (uint i = 0; i < owners.length; i++) {
checkpoint(assets[i], owners[i]);
}
}

/**
* @dev Checks if a CDP is active.
* @param asset Address of the asset.
* @param owner Address of the owner.
* @return alive Boolean indicating if the CDP is active.
*/
function isAlive(address asset, address owner) public view returns (bool) {
return vault.debts(asset, owner) != 0;
}

/**
* @dev Checks if a CDP is listed in the registry.
* @param asset Address of the asset.
* @param owner Address of the owner.
* @return listed Boolean indicating if the CDP is listed.
*/
function isListed(address asset, address owner) public view returns (bool) {
if (cdpList[asset].length == 0) { return false; }
return cdpIndex[asset][owner] != 0 || cdpList[asset][0] == owner;
}

/**
* @dev Internal function to remove a CDP from the registry.
* @param asset Address of the asset.
* @param owner Address of the owner.
*/
function _removeCdp(address asset, address owner) internal {
uint id = cdpIndex[asset][owner];

Expand All @@ -85,13 +125,23 @@ contract CDPRegistry {
emit Removed(asset, owner);
}

/**
* @dev Internal function to add a CDP to the registry.
* @param asset Address of the asset.
* @param owner Address of the owner.
*/
function _addCdp(address asset, address owner) internal {
cdpIndex[asset][owner] = cdpList[asset].length;
cdpList[asset].push(owner);

emit Added(asset, owner);
}

/**
* @dev Retrieves the list of CDPs for a given collateral.
* @param asset Address of the asset.
* @return cdps Array of CDP structs.
*/
function getCdpsByCollateral(address asset) external view returns (CDP[] memory cdps) {
address[] memory owners = cdpList[asset];
cdps = new CDP[](owners.length);
Expand All @@ -100,6 +150,11 @@ contract CDPRegistry {
}
}

/**
* @dev Retrieves the list of CDPs for a given owner.
* @param owner Address of the owner.
* @return r Array of CDP structs.
*/
function getCdpsByOwner(address owner) external view returns (CDP[] memory r) {
address[] memory assets = cr.collaterals();
CDP[] memory cdps = new CDP[](assets.length);
Expand All @@ -116,9 +171,12 @@ contract CDPRegistry {
for (uint i = 0; i < actualCdpsCount; i++) {
r[i] = cdps[i];
}

}

/**
* @dev Retrieves the list of all CDPs in the registry.
* @return r Array of CDP structs.
*/
function getAllCdps() external view returns (CDP[] memory r) {
uint totalCdpCount = getCdpsCount();

Expand All @@ -135,13 +193,22 @@ contract CDPRegistry {
}
}

/**
* @dev Retrieves the total count of CDPs in the registry.
* @return totalCdpCount The total count of CDPs.
*/
function getCdpsCount() public view returns (uint totalCdpCount) {
address[] memory assets = cr.collaterals();
for (uint i = 0; i < assets.length; i++) {
totalCdpCount += cdpList[assets[i]].length;
}
}

/**
* @dev Retrieves the count of CDPs for a given collateral.
* @param asset Address of the asset.
* @return The count of CDPs for the given collateral.
*/
function getCdpsCountForCollateral(address asset) public view returns (uint) {
return cdpList[asset].length;
}
Expand Down
62 changes: 47 additions & 15 deletions contracts/CollateralRegistry.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,41 @@
pragma solidity ^0.7.1;
pragma experimental ABIEncoderV2;


import "./VaultParameters.sol";


/**
* @title CollateralRegistry
**/
* @dev Manages a registry of collateral assets for Unit Protocol.
*/
contract CollateralRegistry is Auth {

/**
* @dev Emitted when a new collateral is added to the registry.
* @param asset The address of the collateral asset added.
*/
event CollateralAdded(address indexed asset);

/**
* @dev Emitted when a collateral is removed from the registry.
* @param asset The address of the collateral asset removed.
*/
event CollateralRemoved(address indexed asset);

/**
* @dev Mapping from collateral asset addresses to their respective ID.
*/
mapping(address => uint) public collateralId;

/**
* @dev List of all collateral asset addresses.
*/
address[] public collateralList;


/**
* @dev Initializes the contract with a list of collateral assets.
* @param _vaultParameters The address of the VaultParameters contract.
* @param assets The initial list of collateral asset addresses.
*/
constructor(address _vaultParameters, address[] memory assets) Auth(_vaultParameters) {
for (uint i = 0; i < assets.length; i++) {
require(!isCollateral(assets[i]), "Unit Protocol: ALREADY_EXIST");
Expand All @@ -31,49 +50,62 @@ contract CollateralRegistry is Auth {
}
}

/**
* @dev Adds a new collateral asset to the registry.
* @param asset The address of the collateral asset to add.
* @notice Only the manager can call this function.
*/
function addCollateral(address asset) public onlyManager {
require(asset != address(0), "Unit Protocol: ZERO_ADDRESS");

require(!isCollateral(asset), "Unit Protocol: ALREADY_EXIST");

collateralId[asset] = collateralList.length;
collateralList.push(asset);

emit CollateralAdded(asset);
}

/**
* @dev Removes a collateral asset from the registry.
* @param asset The address of the collateral asset to remove.
* @notice Only the manager can call this function.
*/
function removeCollateral(address asset) public onlyManager {
require(asset != address(0), "Unit Protocol: ZERO_ADDRESS");

require(isCollateral(asset), "Unit Protocol: DOES_NOT_EXIST");

uint id = collateralId[asset];

delete collateralId[asset];

uint lastId = collateralList.length - 1;

if (id != lastId) {
address lastCollateral = collateralList[lastId];
collateralList[id] = lastCollateral;
collateralId[lastCollateral] = id;
}

collateralList.pop();

emit CollateralRemoved(asset);
}

/**
* @dev Checks if an address is a collateral in the registry.
* @param asset The address to check.
* @return True if the address is a collateral, false otherwise.
*/
function isCollateral(address asset) public view returns(bool) {
if (collateralList.length == 0) { return false; }
return collateralId[asset] != 0 || collateralList[0] == asset;
}

/**
* @dev Returns the list of all collateral assets in the registry.
* @return An array of addresses of the collateral assets.
*/
function collaterals() external view returns (address[] memory) {
return collateralList;
}

/**
* @dev Returns the count of collateral assets in the registry.
* @return The count of collateral assets.
*/
function collateralsCount() external view returns (uint) {
return collateralList.length;
}
}
}
24 changes: 22 additions & 2 deletions contracts/Migrations.sol
Original file line number Diff line number Diff line change
@@ -1,21 +1,41 @@
// SPDX-License-Identifier: bsl-1.1


pragma solidity 0.7.6;

/*
* @title Migrations
* @dev This contract is used to manage migrations of the smart contract code.
* It keeps track of the last completed migration script.
*/
contract Migrations {
/* @dev Address of the contract owner. */
address public owner;

/* @dev Stores the last completed migration script number. */
uint public last_completed_migration;

/*
* @dev Sets the original owner of the contract to the sender account on contract creation.
*/
constructor() {
owner = msg.sender;
}

/*
* @dev Modifier to restrict the execution of functions to only the owner of the contract.
* Reverts if the sender is not the owner.
*/
modifier restricted() {
if (msg.sender == owner) _;
_;
}

/*
* @notice Sets the last completed migration script number.
* @param completed The number of the last completed migration.
* @dev Can only be called by the current owner of the contract.
*/
function setCompleted(uint completed) public restricted {
last_completed_migration = completed;
}
}
}
Loading