Skip to content

Instantly share code, notes, and snippets.

@owenThurm
Last active March 6, 2023 16:36
Show Gist options
  • Save owenThurm/0f6121edcf055462208fbead7a5a7298 to your computer and use it in GitHub Desktop.
Save owenThurm/0f6121edcf055462208fbead7a5a7298 to your computer and use it in GitHub Desktop.
Practice Exam 1
// SPDX-License-Identifier: MIT
pragma solidity 0.8.17;
// Allows user to swap deposited token for another
contract SwapProtocol {
// token address -> user address balance
mapping(address => mapping(address => uint256)) balances;
// ...
function depositForSwap(address token, uint256 amount) external {
require( token != address(0), "Token not supported");
require(amount > 0, "Amount must be greater than zero");
balances [token][msg.sender] + amount;
(bool success, bytes memory data) = token.call(abi.encodeWithSelector(
bytes4(0x23b872dd), // bytes4(keccak256(bytes ("transfer From(address, address, uint256)")))
msg.sender,
address(this),
amount
));
require(success && (data.length == 0 || abi.decode(data, (bool))), "transferFrom failed");
}
}
// SPDX-License-Identifier: MIT
pragma solidity 0.8.17;
import "@openzeppelin/contracts/utils/Address.sol";
interface IERC20Impl {
function balanceOf(address account) external view returns (uint256);
function transfer(address recipient, uint256 amount) external returns (bool);
function allowance(address owner, address spender) external view returns (uint256);
function approve(address spender, uint256 amount) external returns (bool);
function increaseAllowance(address spender, uint256 addedValue) external returns (bool);
function transferFrom(
address sender,
address recipient,
uint256 amount
) external returns (bool);
}
// Used by 3rd parties to integrate with the protocol
interface ITransferWithBeneficiary {
// Transfer an `amount` of tokens to the beneficiary, along with some data
function transferWithBeneficiary(address token, uint256 amount, address beneficiary, uint64 data) external returns (bool);
}
contract FundLocker {
// Release funds to a contract
function releaseFunds(
address token,
address contractAddr,
address beneficiary,
uint256 amount,
uint64 data
) internal {
// Safety checks to ensure msg.sender is withdrawing only their deposited locked funds.
// ...
require(Address.isContract(token), "The given token address is not a contract");
require(Address.isContract(contractAddr), "The given recipient address is not a contract");
IERC20Impl(token).increaseAllowance(contractAddr, amount);
ITransferWithBeneficiary(contractAddr).transferWithBeneficiary(token, amount, beneficiary, data);
}
}
// SPDX-License-Identifier: GPL-3.0
pragma solidity 0.8.17;
contract Token {
mapping(address => uint256) _balances;
mapping(address => mapping(address => uint256)) private _allowances;
function transferFrom(address from, address to, uint256 amount) public returns (bool) {
_spendAllowance(from, msg.sender, amount);
_transfer(from, to, amount);
return true;
}
function approve(address spender, uint256 amount) public returns (bool) {
_approve(msg.sender, spender, amount);
return true;
}
function _approve(address owner, address spender, uint256 amount) internal {
_allowances[owner][spender] = amount;
}
function _spendAllowance(address owner, address spender, uint256 amount) internal {
uint256 currentAllowance = _allowances[owner][spender];
if (currentAllowance != type(uint256).max) _approve(owner, spender, currentAllowance - amount);
}
function _transfer(address from, address to, uint256 amount) internal {
uint256 fromBalance = _balances[from];
_balances[from] = fromBalance - amount;
_balances[to] += amount;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment