-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathRealAssetDepositaryBalanceView.sol
129 lines (106 loc) · 3.65 KB
/
RealAssetDepositaryBalanceView.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
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
pragma experimental ABIEncoderV2;
import "@openzeppelin/contracts/math/SafeMath.sol";
import "../utils/AccessControl.sol";
import "./IDepositaryBalanceView.sol";
contract RealAssetDepositaryBalanceView is IDepositaryBalanceView, AccessControl {
using SafeMath for uint256;
/// @notice Signed data of asset information.
struct Proof {
string data;
string signature;
}
/// @notice Asset information.
struct Asset {
string id;
uint256 amount;
uint256 price;
}
/// @notice The number of assets in depositary.
uint256 public maxSize;
/// @notice Decimals balance.
uint256 public override decimals = 6;
/// @notice Assets list.
Asset[] public portfolio;
/// @dev Assets list index.
mapping(string => uint256) internal portfolioIndex;
/// @notice An event thats emitted when asset updated in portfolio.
event AssetUpdated(string id, uint256 updatedAt, Proof proof);
/// @notice An event thats emitted when asset removed from portfolio.
event AssetRemoved(string id);
/**
* @param _decimals Decimals balance.
* @param _maxSize Max number assets in depositary.
*/
constructor(uint256 _decimals, uint256 _maxSize) public {
decimals = _decimals;
maxSize = _maxSize;
}
/**
* @return Assets count of depositary.
*/
function size() public view returns (uint256) {
return portfolio.length;
}
/**
* @return Assets list.
*/
function assets() external view returns (Asset[] memory) {
Asset[] memory result = new Asset[](size());
for (uint256 i = 0; i < size(); i++) {
result[i] = portfolio[i];
}
return result;
}
/**
* @notice Update information of asset.
* @param id Asset identificator.
* @param amount Amount of asset.
* @param price Cost of one asset in base currency.
* @param updatedAt Timestamp of updated.
* @param proofData Signed data.
* @param proofSignature Data signature.
*/
function put(
string calldata id,
uint256 amount,
uint256 price,
uint256 updatedAt,
string calldata proofData,
string calldata proofSignature
) external onlyAllowed {
require(size() < maxSize, "RealAssetDepositaryBalanceView::put: too many assets");
uint256 valueIndex = portfolioIndex[id];
if (valueIndex != 0) {
portfolio[valueIndex.sub(1)] = Asset(id, amount, price);
} else {
portfolio.push(Asset(id, amount, price));
portfolioIndex[id] = size();
}
emit AssetUpdated(id, updatedAt, Proof(proofData, proofSignature));
}
/**
* @notice Remove information of asset.
* @param id Asset identificator.
*/
function remove(string calldata id) external onlyAllowed {
uint256 valueIndex = portfolioIndex[id];
require(valueIndex != 0, "RealAssetDepositaryBalanceView::remove: asset already removed");
uint256 toDeleteIndex = valueIndex.sub(1);
uint256 lastIndex = size().sub(1);
Asset memory lastValue = portfolio[lastIndex];
portfolio[toDeleteIndex] = lastValue;
portfolioIndex[lastValue.id] = toDeleteIndex.add(1);
portfolio.pop();
delete portfolioIndex[id];
emit AssetRemoved(id);
}
function balance() external view override returns (uint256) {
uint256 result;
for (uint256 i = 0; i < size(); i++) {
result = result.add(portfolio[i].amount.mul(portfolio[i].price));
}
return result;
}
}