Skip to content

Commit

Permalink
feat: add swapAndDonate to GrantRoundManager
Browse files Browse the repository at this point in the history
  • Loading branch information
thelostone-mc authored and mds1 committed Aug 2, 2021
1 parent ca687e4 commit 68ed43b
Show file tree
Hide file tree
Showing 2 changed files with 129 additions and 0 deletions.
76 changes: 76 additions & 0 deletions contracts/contracts/GrantRoundManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,15 @@ import "./GrantRound.sol";
contract GrantRoundManager {
using Address for address;

/// @notice Donation Object
struct Donation {
uint96 grantId; // grant ID to which donation is being made
uint256 amount; // amount of tokens which are being donated
address[] swapPath; // Uniswap router swap path
// WHY IS THIS AN ARRAY ? CAN THIS BE IERC20
GrantRound[] rounds; // rounds against which the donation should be counted
}

/// @notice Address of the GrantRegistry
GrantRegistry public immutable registry;

Expand All @@ -22,6 +31,9 @@ contract GrantRoundManager {
/// @notice Emitted when a new GrantRound contract is created
event GrantRoundCreated(address grantRound);

/// @notice Emit when a donation has been made
event GrantDonation(uint96 grantId, address inputToken, uint256 amount, address[] rounds);

constructor(
GrantRegistry _registry,
ISwapRouter _router,
Expand Down Expand Up @@ -68,4 +80,68 @@ contract GrantRoundManager {

emit GrantRoundCreated(address(_grantRound));
}

/**
* @notice Swap and donate to a grant
* @param _donation Donation being made to a grant
*/
function swapAndDonate(
Donation calldata _donation
) external {

uint96 grantId = _donation.grantId;
GrantRound[] rounds = _donation.rounds;

// Checks to ensure grant recieving donation exists in registry
require(
grantId < registry.grantCount(),
"GrantRoundManager: Grant does not exist in registry provided"
);

/**
* Iterates through every GrantRound to ensure it has the
* - same donationToken as the GrantRoundManager
* - GrantRound is active
*/
for (uint i = 0; i <= rounds.length; i++) {
require(
donationToken == rounds[i].donationToken(),
"GrantRoundManager: GrantRound has a donationToken from GrantRoundManager."
);

require(
block.timestamp >= rounds[i].startTime() &&
block.timestamp < rounds[i].endTime(),
"GrantRoundManager: GrantRound is not active"
);
}

address payoutAddress = registry.getGrantPayee(grantId);
uint256 amountIn = _donation.amount;
address tokenIn = _donation.swapPath[0];

if (tokenIn == donationToken) {
// Uses safeTransfer if the Donation is made in the same donationToken
donationToken.safeTransfer(payoutAddress, amountIn);

emit GrantDonation(grantId, donationToken, amountIn, rounds);
} else {

// Swaps the donation into donationToken using SwapRouter
ISwapRouter.ExactInputSingleParams memory params = ISwapRouter.ExactInputSingleParams(
tokenIn, // tokenIn
donationToken, // tokenOut
fee, // TODO
payoutAddress, // recipient
deadline, // TODO
amountIn, // amountIn
amountOutMinimum, // TODO
0 // sqrtPriceLimitX96
);

uint amountOut = router.exactInputSingle(params);
// TODO: DO we also want to emit event for the actual donation
emit GrantDonation(grantId, donationToken, amountOut, rounds);
}
}
}
53 changes: 53 additions & 0 deletions contracts/scripts/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,15 @@
*/

// --- External imports ---
import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers';
import { ContractFactory } from 'ethers';
import { ethers, network } from 'hardhat';

import {
abi as SWAP_ROUTER_ABI,
bytecode as SWAP_ROUTER_BYTECODE,
} from '@uniswap/v3-periphery/artifacts/contracts/SwapRouter.sol/SwapRouter.json'

// --- Constants ---
// Define grants to create (addresses are random)
const grants = [
Expand All @@ -30,6 +36,51 @@ const grants = [
},
];


const createGrantRoundFactory = async (deployer: SignerWithAddress, registry_address: String) => {

// --- ISwapRouter --
const routerArgs = {
_factory: '0x0',
_WETH9: '0x0'
};

const SwapRouter: ContractFactory = await ethers.getContractFactory(SWAP_ROUTER_ABI, SWAP_ROUTER_BYTECODE);
const router = await (await SwapRouter.deploy(routerArgs)).deployed();
console.log(`Deployed SwapRouter to ${router.address}`);


// --- GrantRoundManager --
const grantRoundManagerArgs = {
registry: registry_address,
router: router,
donationToken: '0x8ad3aa5d5ff084307d28c8f514d7a193b2bfe725',
}

const GrantRoundFactory: ContractFactory = await ethers.getContractFactory('GrantRoundManager', deployer);
const roundFactory = await (await GrantRoundFactory.deploy(grantRoundManagerArgs)).deployed();
console.log(`Deployed GrantRoundFactory to ${roundFactory.address}`);

// --- GRANT ROUND ---
const startDate = new Date();
const endDate = startDate;
endDate.setDate(endDate.getDate() + 7);

// GrantRound Argument
const owner = '0x34f4E532a33EB545941e914B25Efe348Aea31f0A';
const payoutAdmin = '0x06c94663E5884BE4cCe85F0869e95C7712d34803';
const startTime = startDate.getTime();
const endTime = endDate.getTime();
const metaPtr = 'https://time-travel.eth.link';
const minContribution = ethers.constants.One;

await roundFactory.createGrantRound(
owner, payoutAdmin, startTime, endTime, metaPtr, minContribution
);
console.log(`Created GrantRound`);
};


// --- Method to execute ---
async function main(): Promise<void> {
// Only run on Hardhat network
Expand All @@ -46,6 +97,8 @@ async function main(): Promise<void> {
// Create the grants
await Promise.all(grants.map((grant) => registry.createGrant(grant.owner, grant.payee, grant.metaPtr)));
console.log(`Created ${grants.length} dummy grants`);

// await createGrantRoundFactory(deployer, registry.address);
}

// --- Execute main() ---
Expand Down

0 comments on commit 68ed43b

Please sign in to comment.