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

Create SpaceBalance contract #12

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
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
32 changes: 13 additions & 19 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,22 +1,16 @@
# tools api key
ETHERSCAN_API_KEY=
INFURA_PROJECT_ID=
BSCSCAN_API_KEY=
FTMSCAN_API_KEY=
POLYGONSCAN_API_KEY=
ARBISCAN_API_KEY=
# deploy contract account
RINKEBY_PRIVATE_KEY=
MAINNET_PRIVATE_KEY=
BSC_TESTNET_PRIVATE_KEY=
BSC_MAINNET_PRIVATE_KEY=
MATIC_MAINNET_PRIVATE_KEY=
MATIC_TESTNET_PRIVATE_KEY=
AVALANCHE_MAINNET_PRIVATE_KEY=
FANTOM_MAINNET_PRIVATE_KEY=
ARBITRUM_MAINNET_PRIVATE_KEY=
# contract args
# contract args - spacestation & starnft
GALAXY_SIGNER=
CAMPAIGN_SETTER=
CONTRACT_OWNER=
TREASURE_MANAGER=
TREASURE_MANAGER=

# contract args - spacebalance
SPACE_BALANCE_OWNER=
SPACE_BALANCE_TREASURER=

# deployer
DEPLOYER_PRIVATE_KEY=

# misc
ETHERSCAN_API_KEY=
ALCHEMY_KEY=
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*.sol linguist-language=Solidity
17 changes: 9 additions & 8 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
node_modules
build/
node_modules/
.DS_Store
deployments/
env/
.env
coverage
bin/
solc
coverage/
coverage.json
typechain
build

#Hardhat files
cache
artifacts
yarn-error.log
1 change: 1 addition & 0 deletions .husky/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
_
1 change: 1 addition & 0 deletions .nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
v18.15.0
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
[![Discord](https://img.shields.io/discord/824767871183355954?color=green&style=flat-square&logo=discord)](https://discordapp.com/invite/projectgalaxy)
[![Telegram](https://img.shields.io/badge/Telegram-Follow-blue?style=flat-square&logo=telegram)](https://t.me/ProjectGalaxyHQ)

# Project Galaxy Contracts
# Galxe contracts

> This doc is still working in progress

Expand Down
24 changes: 4 additions & 20 deletions contracts/Distributor/MerkleDistributor.sol
Original file line number Diff line number Diff line change
@@ -1,26 +1,10 @@
/*
Copyright 2021 Project Galaxy.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

SPDX-License-Identifier: Apache License, Version 2.0
*/
// SPDX-License-Identifier: Apache-2.0

pragma solidity 0.7.6;

import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/cryptography/MerkleProof.sol";
import "openzeppelin-contracts-3.4/token/ERC20/IERC20.sol";
import "openzeppelin-contracts-3.4/access/Ownable.sol";
import "openzeppelin-contracts-3.4/cryptography/MerkleProof.sol";
import "../interfaces/IMerkleDistributor.sol";

contract MerkleDistributor is IMerkleDistributor, Ownable {
Expand Down
238 changes: 238 additions & 0 deletions contracts/SpaceBalance/SpaceBalance.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,238 @@
// SPDX-License-Identifier: Apache-2.0

pragma solidity >=0.8.0;

import "openzeppelin-contracts-4.8/token/ERC20/IERC20.sol";
import "openzeppelin-contracts-4.8/token/ERC20/utils/SafeERC20.sol";
import "openzeppelin-contracts-4.8/access/Ownable.sol";
import "openzeppelin-contracts-4.8/security/Pausable.sol";

/**
* @title SpaceBalance
* @author Galxe
*
* SpaceBalance contract allows Galxe to charge and keep track of Galxe Space balances.
*/
contract SpaceBalance is Pausable, Ownable {
using SafeERC20 for IERC20;

/* ============ Events ============ */

event UpdateTreasurer(address indexed newTreasurer);

event Deposit(
uint256 indexed _space,
IERC20 indexed token,
uint256 _amount,
address indexed depositor
);

event Withdraw(
uint256 indexed _space,
IERC20 token,
uint256 indexed _amount,
address indexed recipient
);

event AllowToken(IERC20 indexed token);

event DisallowToken(IERC20 indexed token);

/* ============ Modifiers ============ */

modifier onlyTreasurer() {
_onlyTreasurer();
_;
}

modifier onlyAllowedToken(IERC20 token) {
_onlyAllowedToken(token);
_;
}

function _onlyTreasurer() internal view {
require(msg.sender == treasurer, "Must be treasurer");
}

function _onlyAllowedToken(IERC20 token) internal view {
require(tokenAllowlist[token] == true, "Must be allowed token");
}

/* ============ State Variables ============ */

// Contract factory
address public factory;

// Galxe treasurer
address public treasurer;

// Galxe Space => token => current balance
mapping(uint256 => mapping(IERC20 => uint256)) public spaceTokenBalance;

// Galxe Space => token => total deposited amount
mapping(uint256 => mapping(IERC20 => uint256)) public spaceTotalDeposits;

// Allowed ERC20 tokens
mapping(IERC20 => bool) public tokenAllowlist;

/* ============ Constructor ============ */

constructor(address _factory) {
factory = _factory;
transferOwnership(_factory);
}

/* ============ Initializer ============ */

function initialize(address _owner, address _treasurer) external {
require(msg.sender == factory, "Forbidden");
treasurer = _treasurer;
transferOwnership(_owner);
}

/* ============ External Functions ============ */

function setTreasurer(address _treasurer) external onlyOwner {
require(
_treasurer != address(0),
"Treasurer address must not be null address"
);
treasurer = _treasurer;
emit UpdateTreasurer(_treasurer);
}

function allowToken(IERC20 _token) external onlyOwner {
tokenAllowlist[_token] = true;

emit AllowToken(_token);
}

function disallowToken(IERC20 _token) external onlyOwner {
tokenAllowlist[_token] = false;

emit DisallowToken(_token);
}

function pause() public onlyOwner {
_pause();
}

function unpause() public onlyOwner {
_unpause();
}

function isTokenAllowed(IERC20 _token) public view returns (bool) {
return tokenAllowlist[_token];
}

function balanceOf(
uint256 _space,
IERC20 _token
) public view returns (uint256) {
return spaceTokenBalance[_space][_token];
}

/**
* @notice
* Returns accumulated token disposit amount for space.
*/
function totalDepositOf(
uint256 _space,
IERC20 _token
) public view returns (uint256) {
return spaceTotalDeposits[_space][_token];
}

function deposit(
uint256 _space,
IERC20 _token,
uint256 _amount
) external whenNotPaused onlyAllowedToken(_token) {
require(
IERC20(_token).balanceOf(msg.sender) >= _amount,
"Your token amount must be greater then you are trying to deposit"
);
require(
IERC20(_token).allowance(msg.sender, address(this)) >= _amount,
"Approve tokens first!"
);

IERC20(_token).safeTransferFrom(msg.sender, address(this), _amount);
spaceTokenBalance[_space][_token] += _amount;
spaceTotalDeposits[_space][_token] += _amount;

emit Deposit(_space, _token, _amount, msg.sender);
}

function withdraw(
uint256 _space,
IERC20 _token,
address _recipient
) external whenNotPaused onlyTreasurer {
uint256 _amount = spaceTokenBalance[_space][_token];
_withdraw(_space, _token, _amount, _recipient);
}

function withdraw(
uint256 _space,
IERC20 _token,
uint256 _amount,
address _recipient
) external whenNotPaused onlyTreasurer {
_withdraw(_space, _token, _amount, _recipient);
}

function _withdraw(
uint256 _space,
IERC20 _token,
uint256 _amount,
address _recipient
) internal {
require(_amount > 0, "Cannot withdraw a non-positive amount");
require(
spaceTokenBalance[_space][_token] >= _amount,
"Token amount must be greater than withdraw amount"
);
spaceTokenBalance[_space][_token] -= _amount;
_token.safeTransfer(_recipient, _amount);
emit Withdraw(_space, _token, _amount, _recipient);
}

function withdrawBatch(
uint256 _space,
IERC20[] calldata _tokens,
address _recipient
) external whenNotPaused onlyTreasurer {
uint256[] memory _amounts = new uint256[](_tokens.length);
for (uint256 i = 0; i < _tokens.length; ++i) {
_amounts[i] = spaceTokenBalance[_space][_tokens[i]];
}
_withdrawBatch(_space, _tokens, _amounts, _recipient);
}

function withdrawBatch(
uint256 _space,
IERC20[] calldata _tokens,
uint256[] memory _amounts,
address _recipient
) external whenNotPaused onlyTreasurer {
_withdrawBatch(_space, _tokens, _amounts, _recipient);
}

function _withdrawBatch(
uint256 _space,
IERC20[] calldata _tokens,
uint256[] memory _amounts,
address _recipient
) internal {
require(
_tokens.length == _amounts.length,
"Tokens and amounts length mismatch"
);
for (uint256 i = 0; i < _amounts.length; ++i) {
uint256 _amount = _amounts[i];
IERC20 _token = _tokens[i];
_withdraw(_space, _token, _amount, _recipient);
}
}
}
28 changes: 6 additions & 22 deletions contracts/SpaceStation/SpaceStationV2.sol
Original file line number Diff line number Diff line change
@@ -1,28 +1,12 @@
/*
Copyright 2021 Project Galaxy.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

SPDX-License-Identifier: Apache License, Version 2.0
*/
// SPDX-License-Identifier: Apache-2.0

pragma solidity 0.7.6;

import {Address} from "@openzeppelin/contracts/utils/Address.sol";
import {SafeMath} from "@openzeppelin/contracts/math/SafeMath.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {EIP712} from "@openzeppelin/contracts/drafts/EIP712.sol";
import {ECDSA} from "@openzeppelin/contracts/cryptography/ECDSA.sol";
import {Address} from "openzeppelin-contracts-3.4/utils/Address.sol";
import {SafeMath} from "openzeppelin-contracts-3.4/math/SafeMath.sol";
import {IERC20} from "openzeppelin-contracts-3.4/token/ERC20/IERC20.sol";
import {EIP712} from "openzeppelin-contracts-3.4/drafts/EIP712.sol";
import {ECDSA} from "openzeppelin-contracts-3.4/cryptography/ECDSA.sol";
import {ISpaceStation} from "../interfaces/ISpaceStation.sol";
import {IStarNFT} from "../interfaces/IStarNFT.sol";

Expand Down
Loading