Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add UUPS upgradable proxy contract #121

Merged
merged 7 commits into from
Jan 11, 2024
Merged
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
3 changes: 2 additions & 1 deletion .env.example
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
PRIVATE_KEY=
POLYGONSCAN_API_KEY=
ADMIN_ADDRESS=
PAYER_ADDRESS=
PAYER_ADDRESS=
ETHERSCAN_API_KEY=
216 changes: 216 additions & 0 deletions .openzeppelin/sepolia.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,216 @@
{
"manifestVersion": "3.2",
"proxies": [
{
"address": "0x23414482493235D3382b9B1DBF8054832d0C6A69",
"txHash": "0x8fffed82c7ce144069677ebdd8e60801051dd19ac37d0887e70ae04dcfd664f6",
"kind": "uups"
},
{
"address": "0xEa5ed7a3Ea7b5EA066ffbf34f240E6cA23b1f19b",
"txHash": "0x61c21575f7f9724dc37d3d32aa4332b3338c05a86532a6f5e8264c3c355a7115",
"kind": "uups"
}
],
"impls": {
"a490e2077e9a6178a6b60fa4376024b01484cd700870b4c84abcc25b4eb6e8f6": {
"address": "0x1D7a1d4f99085b24f866d039Bf9425Dd36146FE6",
"txHash": "0xebde0f360302df6b4cec17c9c7345abd8e663a9077b6286d8cce1db42aa39a3d",
"layout": {
"solcVersion": "0.8.21",
"storage": [
{
"label": "admin",
"offset": 0,
"slot": "0",
"type": "t_address",
"contract": "StreamManagerStorageV1",
"src": "contracts\\StreamManagerStorageV1.sol:18"
},
{
"label": "payer",
"offset": 0,
"slot": "1",
"type": "t_address",
"contract": "StreamManagerStorageV1",
"src": "contracts\\StreamManagerStorageV1.sol:20"
},
{
"label": "streamInstances",
"offset": 0,
"slot": "2",
"type": "t_mapping(t_address,t_struct(OpenStream)3212_storage)",
"contract": "StreamManagerStorageV1",
"src": "contracts\\StreamManagerStorageV1.sol:22"
},
{
"label": "isPayee",
"offset": 0,
"slot": "3",
"type": "t_mapping(t_address,t_bool)",
"contract": "StreamManagerStorageV1",
"src": "contracts\\StreamManagerStorageV1.sol:24"
},
{
"label": "__gap__",
"offset": 0,
"slot": "4",
"type": "t_array(t_uint256)64_storage",
"contract": "StreamManagerStorageV1",
"src": "contracts\\StreamManagerStorageV1.sol:26"
}
],
"types": {
"t_bool": {
"label": "bool",
"numberOfBytes": "1"
},
"t_struct(InitializableStorage)10_storage": {
"label": "struct Initializable.InitializableStorage",
"members": [
{
"label": "_initialized",
"type": "t_uint64",
"offset": 0,
"slot": "0"
},
{
"label": "_initializing",
"type": "t_bool",
"offset": 8,
"slot": "0"
}
],
"numberOfBytes": "32"
},
"t_struct(ReentrancyGuardStorage)118_storage": {
"label": "struct ReentrancyGuardUpgradeable.ReentrancyGuardStorage",
"members": [
{
"label": "_status",
"type": "t_uint256",
"offset": 0,
"slot": "0"
}
],
"numberOfBytes": "32"
},
"t_uint256": {
"label": "uint256",
"numberOfBytes": "32"
},
"t_uint64": {
"label": "uint64",
"numberOfBytes": "8"
},
"t_address": {
"label": "address",
"numberOfBytes": "20"
},
"t_array(t_uint256)64_storage": {
"label": "uint256[64]",
"numberOfBytes": "2048"
},
"t_mapping(t_address,t_bool)": {
"label": "mapping(address => bool)",
"numberOfBytes": "32"
},
"t_mapping(t_address,t_struct(OpenStream)3212_storage)": {
"label": "mapping(address => struct StreamManagerStorageV1.OpenStream)",
"numberOfBytes": "32"
},
"t_struct(OpenStream)3212_storage": {
"label": "struct StreamManagerStorageV1.OpenStream",
"members": [
{
"label": "payee",
"type": "t_address",
"offset": 0,
"slot": "0"
},
{
"label": "token",
"type": "t_address",
"offset": 0,
"slot": "1"
},
{
"label": "rate",
"type": "t_uint256",
"offset": 0,
"slot": "2"
},
{
"label": "terminationPeriod",
"type": "t_uint256",
"offset": 0,
"slot": "3"
},
{
"label": "cliffPeriod",
"type": "t_uint256",
"offset": 0,
"slot": "4"
},
{
"label": "createdAt",
"type": "t_uint256",
"offset": 0,
"slot": "5"
},
{
"label": "lastClaimedAt",
"type": "t_uint256",
"offset": 0,
"slot": "6"
},
{
"label": "terminatedAt",
"type": "t_uint256",
"offset": 0,
"slot": "7"
},
{
"label": "isTerminated",
"type": "t_bool",
"offset": 0,
"slot": "8"
}
],
"numberOfBytes": "288"
}
},
"namespaces": {
"erc7201:openzeppelin.storage.ReentrancyGuard": [
{
"contract": "ReentrancyGuardUpgradeable",
"label": "_status",
"type": "t_uint256",
"src": "@openzeppelin\\contracts-upgradeable\\utils\\ReentrancyGuardUpgradeable.sol:40",
"offset": 0,
"slot": "0"
}
],
"erc7201:openzeppelin.storage.Initializable": [
{
"contract": "Initializable",
"label": "_initialized",
"type": "t_uint64",
"src": "@openzeppelin\\contracts-upgradeable\\proxy\\utils\\Initializable.sol:69",
"offset": 0,
"slot": "0"
},
{
"contract": "Initializable",
"label": "_initializing",
"type": "t_bool",
"src": "@openzeppelin\\contracts-upgradeable\\proxy\\utils\\Initializable.sol:73",
"offset": 8,
"slot": "0"
}
]
}
}
}
}
}
4 changes: 2 additions & 2 deletions contracts/MockUSDT.sol
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ contract MockUSDT is ERC20, Ownable {
string memory name,
string memory symbol,
uint8 decimals_
) ERC20(name, symbol) {
) ERC20(name, symbol) Ownable(msg.sender) {
_decimals = decimals_;
}

Expand All @@ -26,4 +26,4 @@ contract MockUSDT is ERC20, Ownable {
function decimals() public view override returns (uint8) {
return _decimals;
}
}
}
64 changes: 36 additions & 28 deletions contracts/StreamManager.sol
Original file line number Diff line number Diff line change
@@ -1,11 +1,21 @@
//SPDX-License-Identifier: Unlicense
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/utils/ReentrancyGuardUpgradeable.sol";

import "../interfaces/IStreamManager.sol";
import "./StreamManagerStorageV1.sol";

contract StreamManager is IStreamManager, ReentrancyGuard {
contract StreamManager is
Initializable,
IStreamManager,
ReentrancyGuardUpgradeable,
UUPSUpgradeable,
StreamManagerStorage
{
using SafeERC20 for IERC20;

/**
Expand Down Expand Up @@ -60,32 +70,6 @@ contract StreamManager is IStreamManager, ReentrancyGuard {
error AlreadyTerminated();
error OpenStreamExists();

struct OpenStream {
address payee;
address token;
uint256 rate;
uint256 terminationPeriod;
uint256 cliffPeriod;
uint256 createdAt;
uint256 lastClaimedAt;
uint256 terminatedAt;
bool isTerminated;
}

///@dev admin address
address public admin;
///@dev payer address
address public payer;
/// @dev payee's address => instance
mapping(address => OpenStream) public streamInstances;
/// @dev payee's address => true/false
mapping(address => bool) public isPayee;

constructor(address _admin, address _payer) {
admin = _admin;
payer = _payer;
}

///@dev check if the caller is payer
modifier onlyPayer() {
if (payer != msg.sender) revert NotPayer();
Expand Down Expand Up @@ -113,6 +97,20 @@ contract StreamManager is IStreamManager, ReentrancyGuard {
_;
}

/// @custom:oz-upgrades-unsafe-allow constructor
constructor() {
_disableInitializers();
}

///@dev proxy initializer
function initialize(address _admin, address _payer) public initializer {
__ReentrancyGuard_init();
__UUPSUpgradeable_init();

admin = _admin;
payer = _payer;
}

///@dev it calculates claimable amount.
function calculate(
address _payee,
Expand Down Expand Up @@ -278,4 +276,14 @@ contract StreamManager is IStreamManager, ReentrancyGuard {
admin = _feeAddress;
emit CommissionAddressChanged(admin);
}

///@dev default override for uups proxies
function _authorizeUpgrade(
address newImplementation
) internal override onlyAdmin {}

///@dev version
function version() public pure virtual returns (string memory) {
return "1.0.0";
}
}
29 changes: 29 additions & 0 deletions contracts/StreamManagerStorageV1.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
//SPDX-License-Identifier: Unlicense
pragma solidity ^0.8.0;

contract StreamManagerStorageV1 {
struct OpenStream {
address payee;
address token;
uint256 rate;
uint256 terminationPeriod;
uint256 cliffPeriod;
uint256 createdAt;
uint256 lastClaimedAt;
uint256 terminatedAt;
bool isTerminated;
}

///@dev admin address
address public admin;
///@dev payer address
address public payer;
/// @dev payee's address => instance
mapping(address => OpenStream) public streamInstances;
/// @dev payee's address => true/false
mapping(address => bool) public isPayee;
/// @dev gap for further storage expansion
uint256[46] private __gap__;
}

abstract contract StreamManagerStorage is StreamManagerStorageV1 {}
Loading
Loading