Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
170 commits
Select commit Hold shift + click to select a range
29784de
fix: only change in logic
0xMotto Feb 21, 2023
b03099a
fix: fix _update1 in Pair.sol
0xMotto Mar 3, 2023
d697c98
fix: fix if/else in _update0 & _update1 in Pair.sol
0xMotto Mar 3, 2023
acb79f3
chore: fix comments
0xMotto Mar 3, 2023
877259c
fix: fix type uint -> uint256
0xMotto Mar 3, 2023
95d39c5
fix: remove getVoter function in PairFactory
0xMotto Mar 3, 2023
519b9fc
fix: remove initial_voter_set and initial_tank_set flag in PairFactory
0xMotto Mar 3, 2023
73005d8
fix: remove initalized flag in WrappedExternalBribeFactory
0xMotto Mar 3, 2023
83e44ed
fix: rename wrappedxbribefactory variable in Voter.sol
0xMotto Mar 3, 2023
783ad5f
chore: remove comments
0xMotto Mar 3, 2023
5ac59e3
fix: use IPair interface in Voter instead of Pair contract to call fu…
0xMotto Mar 3, 2023
02d6e9c
chore: remove comment
0xMotto Mar 3, 2023
1f6952c
chore: remove comment
0xMotto Mar 3, 2023
da83099
fix: can only set external bribe once in Pair.sol
0xMotto Mar 3, 2023
49a7b45
chore: remove commented code
0xMotto Mar 3, 2023
36a57bf
fix: remove index tracking in Pair
0xMotto Mar 3, 2023
4c99326
fix: remove claim event in Pair
0xMotto Mar 3, 2023
b3f88b3
fix: remove claimFees in IPair
0xMotto Mar 3, 2023
7e2d94e
fix: remove Pair fees from Pair.sol
0xMotto Mar 3, 2023
2627315
fix: remove PairFees
0xMotto Mar 3, 2023
086457e
fix: remove claimFees in gauge
0xMotto Mar 3, 2023
62d571a
fix: setHasGauge in killGauge and reviveGauge function in Voter.sol
0xMotto Mar 3, 2023
7a7a488
fix: can set fee to zero
0xMotto Mar 3, 2023
c3202ca
fix: add back checking for setFee in PairFactory
0xMotto Mar 3, 2023
4633950
chore: remove comments
0xMotto Mar 3, 2023
0635e3f
fix: fix code error
0xMotto Mar 3, 2023
eea30e9
feat: add event VoterSet in WrappedExternalBribeFactory
0xMotto Mar 3, 2023
421035d
feat: add events in PairFactory
0xMotto Mar 3, 2023
af5fd00
feat: add events in Pair.sol
0xMotto Mar 3, 2023
4e8343e
fix: Forge config deprecated
c001ie Mar 3, 2023
b6b096c
build: Add yarn.lock
c001ie Mar 3, 2023
6616faf
forge install: openzeppelin-contracts
c001ie Mar 3, 2023
020aab1
chore: Remove Redemption logic
c001ie Mar 3, 2023
d3f20bd
chore: Drop cross-chain redemption logic
c001ie Mar 3, 2023
411f88f
forge install: forge-std
c001ie Mar 3, 2023
24e13a4
forge install: solmate
c001ie Mar 3, 2023
808bd90
build: Remove L0 from gitmodules
c001ie Mar 3, 2023
af760d0
fix: Gauge reward token precision based on ERC20 token decimals
c001ie Mar 3, 2023
1ccb1b8
feat: Allow pair fee to be 0
c001ie Mar 3, 2023
3ab00b0
chore: Remove internal bribe
c001ie Mar 3, 2023
0576065
chore: Remove L0 from gitignore
c001ie Mar 3, 2023
b405f1a
test: MockERC20 no longer needs claimFees
c001ie Mar 3, 2023
8176b68
refactor: Merge _update0 and _update1
c001ie Mar 3, 2023
f412322
build: Initial mint 300m
c001ie Mar 3, 2023
ffec16b
feat: Rename token
c001ie Mar 3, 2023
3dd8acf
refactor: Move initialMint to constructor
c001ie Mar 3, 2023
b9bea6f
refactor: Rename Velo to Flow
c001ie Mar 3, 2023
721e615
fix: Remove claim from IFlow
c001ie Mar 3, 2023
584a6ad
docs: Optimism -> Canto
c001ie Mar 3, 2023
c1e7f1f
chore: amend gitignore
0xMotto Mar 4, 2023
0dfc2e0
fix: add changes
0xMotto Mar 4, 2023
8d5f7ea
feat: add canto csr
0xMotto Mar 4, 2023
3d5501e
feat: add owner in voting escrow
0xMotto Mar 4, 2023
3ec589e
fix: fix failed tests
0xMotto Mar 4, 2023
67fe09a
refactor: Rename VELO to FLOW and fixed a test
c001ie Mar 4, 2023
5f60d42
refactor: Rename VelodromeLibrary to VelocimeterLibrary
c001ie Mar 4, 2023
def0eeb
test: Extract 4 years as a constant
c001ie Mar 4, 2023
e2a6694
test: Extract 1 week as a constant
c001ie Mar 4, 2023
ef1cb38
fix: Variable shadowing
c001ie Mar 4, 2023
c88d385
test: Restrict mutability
c001ie Mar 4, 2023
c3ecebf
fix: Unused functiona arg
c001ie Mar 4, 2023
940e758
fix: Unused local var
c001ie Mar 4, 2023
532e533
fix: set hasGauge/external bribe does not work if _pool is not pair
c001ie Mar 4, 2023
b5bf68a
fix: Voter cannot change in Pair, so no need to emit setter
c001ie Mar 4, 2023
36aaad6
fix: Failing testMinterWeeklyDistribute
c001ie Mar 4, 2023
932d329
build: forge install ds-test
c001ie Mar 4, 2023
64e20c0
fix: Failing testMinterWeeklyDistribute
c001ie Mar 4, 2023
8aab7c7
test: Remove WEVE
c001ie Mar 4, 2023
9ba9164
build: Canto deployment script
c001ie Mar 4, 2023
4ceede9
refactor: Minter.initialize Claim struct
c001ie Mar 4, 2023
2999f9b
build: Mint initialize in deployment
c001ie Mar 4, 2023
a046d81
build: Script to get veNFT snapshot
c001ie Mar 4, 2023
486b621
feat: Allow minter multiple mint and lock
c001ie Mar 4, 2023
f591d12
build: Split batch mint tokens + veNFTs
c001ie Mar 4, 2023
e51e164
build: Migrate mint script
c001ie Mar 4, 2023
972527f
build: Update initial weekly emission to 13m
c001ie Mar 4, 2023
d47024e
build: Team member vesting
c001ie Mar 4, 2023
6e549b4
build: Flow convertor deployment
c001ie Mar 4, 2023
3f93bf0
chore: Remove TODO
c001ie Mar 4, 2023
a832177
build: PairFactory set tank
c001ie Mar 4, 2023
997ba1c
build: Voting escrod set ve art proxy
c001ie Mar 4, 2023
b26ed3a
build: Pair factory set X
c001ie Mar 4, 2023
de2bd56
chore: Initial liquid supply should be 82m
c001ie Mar 4, 2023
a3ec0ef
build: Update whitelisted tokens
c001ie Mar 4, 2023
8eb3213
build: Include snapshotted veNFT holders
c001ie Mar 4, 2023
a7d3a1c
refactor: Move batch mint to function
c001ie Mar 4, 2023
4122ae5
feat: add canto csr
0xMotto Mar 4, 2023
8e341ee
chore: add initial mint for dunks
0xMotto Mar 5, 2023
0168f87
chore: change multi sig claim veNFT from 13 to 14
0xMotto Mar 5, 2023
a9855b8
chore: change asset eoa initial mint from 5 to 4
0xMotto Mar 5, 2023
c9d326b
fix: add csr related code to deployment script
0xMotto Mar 5, 2023
f0629db
fix: remove duplicated setVoter for votingEscrow in deployment script
0xMotto Mar 5, 2023
e779cdf
feat: add FlowConvertor
0xMotto Mar 5, 2023
572b534
chore: amend initial mint
0xMotto Mar 5, 2023
ce8195e
fix: Wrong contract/variable name used
c001ie Mar 5, 2023
b602bc1
fix: Addresses need to be checksummed
c001ie Mar 5, 2023
c5793ae
fix: Unused local variable warning
c001ie Mar 5, 2023
b401330
fix: Wrong function name
c001ie Mar 5, 2023
3144982
fix: Typo
c001ie Mar 5, 2023
a361687
fix: Addresses need to be checksummed
c001ie Mar 5, 2023
d6aae27
Added THREE_MILLIONs = 1%
Ceazor Mar 6, 2023
c119752
fix: typo
0xMotto Mar 6, 2023
933e367
refactor: Rename VELO to FLOW and fixed a test
c001ie Mar 4, 2023
269a911
feat: add canto csr
0xMotto Mar 4, 2023
5f4e339
double check on mints,
Ceazor Mar 6, 2023
a60edd4
remove WAIT Whitelisting. pool shallow
Ceazor Mar 6, 2023
b473f44
fix: remove redundant vairables
0xMotto Mar 6, 2023
6161b0a
Revert "fix: Gauge reward token precision based on ERC20 token decimals"
c001ie Mar 6, 2023
47d635d
fix: remove isPaused = false in constructor
0xMotto Mar 6, 2023
64a1fa1
pair fetch tank from PairFactory so all pairs depend on PF tank()
Ceazor Mar 7, 2023
e74b7da
fix: fix pair tanks
0xMotto Mar 7, 2023
cea2094
transferFrom to transfer
Ceazor Mar 7, 2023
914a4a2
fix: add _csrNftId in constructor of PairFactory
0xMotto Mar 7, 2023
7b5e6aa
chore: fork canto mainnet in hardhat config
0xMotto Mar 7, 2023
3ce0c74
feat: Use Ownable for PairFactory
c001ie Mar 6, 2023
c35d741
Changes to Roles
Ceazor Mar 6, 2023
20ad75a
fix: fix FlowConvertorDeployment.s.sol
0xMotto Mar 7, 2023
5065e33
fix: remove setting owner at constructor of FlowVestor
0xMotto Mar 7, 2023
b63b3a7
chore: update hardhat.config.ts
0xMotto Mar 7, 2023
337a331
test: FlowConvertor redeem test
c001ie Mar 7, 2023
3ac2ef0
fix: use IPairFactory in Pair.sol
0xMotto Mar 8, 2023
83062c4
fix: fix getting wrong pair address in router
0xMotto Mar 8, 2023
72c1414
chore: hardcode deployer eoa address in scripts
0xMotto Mar 8, 2023
ea45a86
chore: push latest hardhat setting
0xMotto Mar 8, 2023
8dafbf5
fix: remove experimental features in router
0xMotto Mar 9, 2023
6e9c591
fix: Handle tax tokens in notifyRewardAmount
c001ie Mar 9, 2023
bce355c
fix: Handle tax tokens in Gauge.notifyRewardAmount
c001ie Mar 9, 2023
2225ec3
fix: reduce MAX_REWARD_TOKENS from 16 to 4 in Gauge
0xMotto Mar 9, 2023
6cb1453
add TaxTkn notifyReward Logic to wExternalBribe
Ceazor Mar 9, 2023
d285c51
fix: transfer all loose tokens to msig after deployment of vesting co…
0xMotto Mar 10, 2023
50ffa43
fix: update deployer eoa wallet
0xMotto Mar 10, 2023
b6a1bba
fix: update deployer eoa wallet
0xMotto Mar 10, 2023
d08cf1d
chore: remove unused address in team vesting deployment script
0xMotto Mar 10, 2023
7a60cde
fix: remove unused constant in Minter.sol
0xMotto Mar 10, 2023
04a0d29
refactor: capitalize constant variables
0xMotto Mar 11, 2023
b2bb5c8
fix: remove duplicated deployOwners
0xMotto Mar 11, 2023
4ff8031
refactor: rename FOUR_YEARS in test cases
0xMotto Mar 11, 2023
0c4dedd
refactor: remove optimismConfig.ts
0xMotto Mar 11, 2023
c994703
chore: remove commented code in hardhat.config.ts
0xMotto Mar 11, 2023
54f3b50
chore: move constant immutable variable tgt in WrappedExternalBribeFa…
0xMotto Mar 11, 2023
692859e
fix: change csrNftId to immutable in Flow.sol
0xMotto Mar 11, 2023
f975dbc
fix: add TURNSTILE address as constant in Flow.sol
0xMotto Mar 11, 2023
9ea99e1
refactor: rename variable amount0 to amount in events of Pair.sol
0xMotto Mar 11, 2023
6ffe615
fix: add wrapped bribe
0xMotto Apr 20, 2023
792e44f
feat: add handle left over bribes
0xMotto Apr 20, 2023
3554df7
fix: add events
0xMotto Apr 20, 2023
a2820f4
fix: add csr to wrapped bribe
0xMotto Apr 20, 2023
31435b3
feat: add updateRewardAmount in wrapped bribe contract for balance di…
0xMotto Apr 23, 2023
417aa09
fix: add test case for updateRewardAmount
0xMotto Apr 23, 2023
a501c31
feat: add autobribe
0xMotto Apr 25, 2023
8632d46
refactor: reuse declared vairables in WrappedBribeFactory
0xMotto Apr 25, 2023
d530a9c
feat: add seal() in AutoBribe
0xMotto Apr 26, 2023
e41e46e
fix: add identifier for sealed in AutoBribe
0xMotto Apr 27, 2023
c630a4d
fix: use non-reserved keyword for variable name in AutoBribe
0xMotto Apr 27, 2023
768381c
feat: update AutoBribe
0xMotto Apr 28, 2023
c41aca5
chore: update deployment script for wrapped bribe factory
0xMotto Apr 28, 2023
9db2161
fix: fix AutoBribe
0xMotto Apr 28, 2023
930bf2d
fix: add tests for setProject
0xMotto Apr 28, 2023
dbb230d
feat: add last updated in wrapped bribe
0xMotto Apr 28, 2023
e700686
fix: fix typo
0xMotto Apr 28, 2023
9ffbfe3
fix: remove createAutoBribe
0xMotto Apr 28, 2023
483497a
fix: remove team in constructor of WrappedBribeFactory
0xMotto Apr 28, 2023
a8398ed
feat: add AutoBribeFactory
0xMotto Apr 28, 2023
f5b35d7
fix: fix test cases
0xMotto Apr 28, 2023
51e8e86
fix
0xMotto Apr 29, 2023
ef2a441
fix: set nextWeek to block.timestamp in constructor
0xMotto May 2, 2023
4468ebb
fix: add checking to avoid re-bribing in the same week
0xMotto May 2, 2023
8ddce9b
fix: amend AutoBribe
0xMotto May 3, 2023
bf563b7
fix: fix data location
0xMotto May 3, 2023
7d31a8d
fix: check bribe token whitelisted in AutoBribe
0xMotto May 23, 2023
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
1 change: 0 additions & 1 deletion .env.example
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
PRIVATE_KEY=
OP_SCAN_API_KEY=
FTM_SCAN_API_KEY=
ALCHEMY_API_KEY=
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,7 @@ abi
build
scripts/xbribes
# for verify
Flattened.sol
Flattened.sol
lib/openzeppelin-contracts
lib/forge-std
lib/ds-test
9 changes: 4 additions & 5 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,11 @@
[submodule "lib/forge-std"]
path = lib/forge-std
url = https://github.com/foundry-rs/forge-std
branch = v1.5.0
[submodule "lib/solmate"]
path = lib/solmate
url = https://github.com/Rari-Capital/solmate
url = https://github.com/transmissions11/solmate
[submodule "lib/openzeppelin-contracts"]
path = lib/openzeppelin-contracts
url = https://github.com/OpenZeppelin/openzeppelin-contracts
[submodule "lib/LayerZero"]
path = lib/LayerZero
url = https://github.com/LayerZero-Labs/LayerZero
url = https://github.com/Openzeppelin/openzeppelin-contracts
branch = v4.8.2
237 changes: 237 additions & 0 deletions contracts/AutoBribe.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,237 @@
// SPDX-License-Identifier: MIT

import "openzeppelin-contracts/contracts/access/Ownable.sol";
import "contracts/interfaces/ITurnstile.sol";
import "contracts/interfaces/IERC20.sol";
import "contracts/interfaces/IVoter.sol";
import "contracts/WrappedBribe.sol";

pragma solidity ^0.8.13;

// the purpose of this contract is to allow the projects to deposit bribes that will bribe their pools for a period of time
// they will need to set up a public keeper, anyone can send the bribes
// bribes are divided evenly into the amount of weeks designated when they deposit
// each new deposit will NOT make a bribe immediately!
// calling the bribe function is public and is rewarded with a share of the bribe token
// !!!!!!!!!!!this contract handles multiple bribe tokens, and a single bribe contract!!!!!!!!!

contract AutoBribe is Ownable {
address public constant TURNSTILE =
0xEcf044C5B4b867CFda001101c617eCd347095B44;
address public immutable voter;
address public immutable wBribe;

address public project;
bool public depositSealed;
bool public initialized;
uint256 public nextWeek;
address[] public bribeTokens;
mapping(address => bool) public bribeTokensDeposited;
mapping(address => uint256) public bribeTokenToWeeksLeft;
string public bribeName;

event Deposited(
address indexed _bribeToken,
uint256 _amount,
uint256 _weeks
);
event Bribed(uint256 indexed _timestamp, address _briber);
event EmptiedOut(uint256 indexed _timestamp, address project);
event Sealed(uint256 indexed _timestamp);
event UnSealed(uint256 indexed _timestamp);

constructor(
address _voter,
address _wBribe,
address _team,
string memory _name,
uint256 _csrNftId
) {
voter = _voter;
wBribe = _wBribe;
nextWeek = block.timestamp;
_transferOwnership(_team);
ITurnstile(TURNSTILE).assign(_csrNftId);
bribeName = _name;
}

//########################################
//###########PUBLIC FUNCTIONS#############
//########################################

//This public function allows anyone to send the weekly allocation to the bribe contract
//There is a small reward for calling this function
//It can only be called once a week
function bribe() public {
require(block.timestamp >= nextWeek, "already bribed this week");
uint256 length = bribeTokens.length;
address _bribeToken;
for (uint256 i = 0; i < length; ) {
_bribeToken = bribeTokens[i];
uint256 weeksLeft = bribeTokenToWeeksLeft[_bribeToken];
uint256 bribeAmount = balance(_bribeToken) / weeksLeft;
uint256 gasReward = bribeAmount / 200;
_safeTransfer(_bribeToken, msg.sender, gasReward);
WrappedBribe(wBribe).notifyRewardAmount(
_bribeToken,
bribeAmount - gasReward
);
bribeTokenToWeeksLeft[_bribeToken] = weeksLeft - 1;
unchecked {
++i;
}
}
nextWeek = nextWeek + 604800;
emit Bribed(nextWeek, msg.sender);
}

//This just returns the balance of bribe tokens in the contract
function balance(address _bribeToken) public view returns (uint) {
return IERC20(_bribeToken).balanceOf(address(this));
}

//########################################
//########PROJECT ADMIN FUNCTIONS#########
//########################################

//Allows project to deposit bribe tokens and set the weeks of which they are divided up into
function deposit(
address _bribeToken,
uint256 _amount,
uint256 _weeks
) public {
require(msg.sender == project, "only the project can bribe");
require(_amount > 0, "Why are you depositing 0 tokens?");
require(_weeks > 0, "You have to put at least 1 week");
require(
IVoter(voter).isWhitelisted(_bribeToken),
"Bribe Token is not whitelisted"
);
_safeTransferFrom(_bribeToken, msg.sender, address(this), _amount);
uint256 allowance = IERC20(_bribeToken).allowance(
address(this),
wBribe
);
_safeApprove(_bribeToken, wBribe, allowance + _amount);
if (!bribeTokensDeposited[_bribeToken]) {
bribeTokensDeposited[_bribeToken] = true;
bribeTokens.push(_bribeToken);
}
bribeTokenToWeeksLeft[_bribeToken] += _weeks;

emit Deposited(_bribeToken, _amount, _weeks);
}

//Allows the project to retrieve their bribe tokens
function emptyOut() public {
require(msg.sender == project, "only project can empty out");
require(!depositSealed, "deposit is sealed");
uint256 length = bribeTokens.length;
uint256 amount;

for (uint256 i = 0; i < length; ) {
address bribeToken = bribeTokens[i];
amount = balance(bribeToken);
bribeTokenToWeeksLeft[bribeToken] = 0;
_safeTransfer(bribeToken, msg.sender, amount);

unchecked {
++i;
}
}

emit EmptiedOut(block.timestamp, project);
}

//Allows project to seal the vault making it not possible for them to withdraw their tokens
function seal() public {
require(msg.sender == project, "only project can seal");
depositSealed = true;

emit Sealed(block.timestamp);
}

//Allows project to change their controlling wallet
function setProject(address _newWallet) public {
require(msg.sender == project);
project = _newWallet;
}

//########################################
//#######VELOCIMETER ADMIN FUNCTIONS######
//########################################

//Allows Velocimeter to re allow project to withdraw their tokens
function unSeal() public onlyOwner {
depositSealed = false;

emit UnSealed(block.timestamp);
}

function initProject(address _newWallet) public onlyOwner {
require(!initialized, "project wallet can only be set once by team");
if (!initialized) {
initialized = true;
}
project = _newWallet;
}

function inCaseTokensGetStuck(address _token) external onlyOwner {
require(!bribeTokensDeposited[_token], "!bribeToken");
uint256 amount = IERC20(_token).balanceOf(address(this));
_safeTransfer(_token, msg.sender, amount);
}

//########################################
//############RECLOCK FUNCTION############
//########################################

// Allows project or Velocimeter to reset the week to the current block
// This should only be called with consideration as it can allow for double bribes in a single week.
// Best use is to call it BEFORE, bribe() is called in a given week
function reclockBribeToNow() external {
require(
msg.sender == project || msg.sender == owner(),
"you can't call this"
);
nextWeek = block.timestamp;
}

//########################################
//############INTERNAL FUNCTIONS##########
//########################################

function _safeTransfer(address token, address to, uint256 value) internal {
require(token.code.length > 0);
(bool success, bytes memory data) = token.call(
abi.encodeWithSelector(IERC20.transfer.selector, to, value)
);
require(success && (data.length == 0 || abi.decode(data, (bool))));
}

function _safeTransferFrom(
address token,
address from,
address to,
uint256 value
) internal {
require(token.code.length > 0);
(bool success, bytes memory data) = token.call(
abi.encodeWithSelector(
IERC20.transferFrom.selector,
from,
to,
value
)
);
require(success && (data.length == 0 || abi.decode(data, (bool))));
}

function _safeApprove(address token, address spender, uint value) internal {
require(token.code.length > 0);
(bool success, bytes memory data) = token.call(
abi.encodeWithSelector(IERC20.approve.selector, spender, value)
);
require(success && (data.length == 0 || abi.decode(data, (bool))));
}
}
15 changes: 11 additions & 4 deletions contracts/ExternalBribe.sol
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.13;

import 'contracts/libraries/Math.sol';
import "openzeppelin-contracts/contracts/utils/math/Math.sol";
import 'contracts/interfaces/IBribe.sol';
import 'contracts/interfaces/IERC20.sol';
import 'contracts/interfaces/IGauge.sol';
import 'contracts/interfaces/IVoter.sol';
import 'contracts/interfaces/IVotingEscrow.sol';
import 'contracts/interfaces/ITurnstile.sol';

// Bribes pay out rewards for a given pool based on the votes that were received from the user (goes hand in hand with Voter.vote())
contract ExternalBribe is IBribe {
address public constant TURNSTILE = 0xEcf044C5B4b867CFda001101c617eCd347095B44;
address public immutable voter; // only voter can modify balances (since it only happens on vote())
address public immutable _ve; // 天使のたまご

uint internal constant DURATION = 7 days; // rewards are released over the voting period
uint internal constant MAX_REWARD_TOKENS = 16;

uint internal constant PRECISION = 10 ** 18;

uint public totalSupply;
mapping(uint => uint) public balanceOf;
mapping(address => mapping(uint => uint)) public tokenRewardsPerEpoch;
Expand Down Expand Up @@ -53,7 +53,7 @@ contract ExternalBribe is IBribe {
event NotifyReward(address indexed from, address indexed reward, uint epoch, uint amount);
event ClaimRewards(address indexed from, address indexed reward, uint amount);

constructor(address _voter, address[] memory _allowedRewardTokens) {
constructor(address _voter, address[] memory _allowedRewardTokens, uint256 _csrNftId) {
voter = _voter;
_ve = IVoter(_voter)._ve();

Expand All @@ -63,6 +63,8 @@ contract ExternalBribe is IBribe {
rewards.push(_allowedRewardTokens[i]);
}
}

ITurnstile(TURNSTILE).assign(_csrNftId);
}

// simple re-entrancy check
Expand Down Expand Up @@ -292,7 +294,12 @@ contract ExternalBribe is IBribe {
uint adjustedTstamp = getEpochStart(block.timestamp);
uint epochRewards = tokenRewardsPerEpoch[token][adjustedTstamp];

uint256 balanceBefore = IERC20(token).balanceOf(address(this));
_safeTransferFrom(token, msg.sender, address(this), amount);
uint256 balanceAfter = IERC20(token).balanceOf(address(this));

amount = balanceAfter - balanceBefore;

tokenRewardsPerEpoch[token][adjustedTstamp] = epochRewards + amount;

periodFinish[token] = adjustedTstamp + DURATION;
Expand Down
Loading