2022-02-14 14:47:01 +00:00
|
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
pragma solidity ^0.8.0;
|
|
|
|
|
|
|
|
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
|
|
|
|
|
|
|
|
contract Collateral {
|
|
|
|
IERC20 private immutable token;
|
2022-02-14 15:43:56 +00:00
|
|
|
Totals private totals;
|
2022-02-14 14:47:01 +00:00
|
|
|
mapping(address => uint256) private balances;
|
|
|
|
|
2022-02-14 15:19:47 +00:00
|
|
|
constructor(IERC20 _token) invariant {
|
2022-02-14 14:47:01 +00:00
|
|
|
token = _token;
|
|
|
|
}
|
|
|
|
|
|
|
|
function balanceOf(address account) public view returns (uint256) {
|
|
|
|
return balances[account];
|
|
|
|
}
|
|
|
|
|
2022-02-14 16:05:05 +00:00
|
|
|
function add(address account, uint256 amount) private {
|
|
|
|
balances[account] += amount;
|
|
|
|
totals.balance += amount;
|
|
|
|
}
|
|
|
|
|
|
|
|
function subtract(address account, uint256 amount) private {
|
|
|
|
balances[account] -= amount;
|
|
|
|
totals.balance -= amount;
|
|
|
|
}
|
|
|
|
|
2022-02-14 15:19:47 +00:00
|
|
|
function deposit(uint256 amount) public invariant {
|
2022-02-14 14:47:01 +00:00
|
|
|
token.transferFrom(msg.sender, address(this), amount);
|
2022-02-14 15:43:56 +00:00
|
|
|
totals.deposited += amount;
|
2022-02-14 16:05:05 +00:00
|
|
|
add(msg.sender, amount);
|
2022-02-14 15:43:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function withdraw() public invariant {
|
2022-02-14 16:05:05 +00:00
|
|
|
uint256 amount = balanceOf(msg.sender);
|
2022-02-14 15:43:56 +00:00
|
|
|
totals.withdrawn += amount;
|
2022-02-14 16:05:05 +00:00
|
|
|
subtract(msg.sender, amount);
|
2022-02-14 15:43:56 +00:00
|
|
|
assert(token.transfer(msg.sender, amount));
|
2022-02-14 15:19:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
modifier invariant() {
|
2022-02-14 15:43:56 +00:00
|
|
|
Totals memory oldTotals = totals;
|
2022-02-14 15:19:47 +00:00
|
|
|
_;
|
2022-02-14 15:43:56 +00:00
|
|
|
assert(totals.deposited >= oldTotals.deposited);
|
|
|
|
assert(totals.withdrawn >= oldTotals.withdrawn);
|
|
|
|
assert(totals.deposited == totals.balance + totals.withdrawn);
|
|
|
|
}
|
|
|
|
|
|
|
|
struct Totals {
|
|
|
|
uint256 balance;
|
|
|
|
uint256 deposited;
|
|
|
|
uint256 withdrawn;
|
2022-02-14 14:47:01 +00:00
|
|
|
}
|
|
|
|
}
|